为什么 useState() 钩子没有按预期工作?

时间:2021-07-11 14:21:18

标签: reactjs input use-state

以下代码未按预期执行。电子邮件设置为电子邮件输入中的第一个字符,其余字符设置为密码。之后,登录功能中的警报显示为空白。我不知道为什么。有人可以解释我并给我一个可行的解决方案吗?

import React, { useState } from "react"

const Auth = () => {
  const signIn = () => {
    alert(email + password)
  }

  const step2 = {
    stepCount: "Step 02/02",
    title: "Enter password",
    helperText: "If you have an account, enter your set password or if you dont't have an account enter a strong password for your acccount.",
    inputType: "password",
    onclickBtnText: "Proceed",
    onclick: (() => {
      setPassword(password)
      signIn()
    })
  }
  const step1 = {
    stepCount: "Step 01/02",
    title: "Enter email",
    helperText: "Enter your email to sign in to your account. Or if you don't have an account no worries! .We will create an account for ya !",
    inputType: "email",
    onclickBtnText: "Next",
    onclick: (() => {
      setEmail(email)
      setStep(step2)
    })
  }
  
  const [step, setStep] = useState(step1)
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')

  const setInput = () => {
    step === step1 ?
      setEmail(email) : setPassword(password)
  }

  return (
    <div style={{ display: "flex", flexFlow: "column", alignItems: "center", }}>
          <h4 style={{ marginTop: "20px", marginBottom: "10px", color: "#a3a3a3", }}>
            {step.stepCount}
          </h4>
          <h2 style={{ marginBottom: "35px" }}>
            {step.title}
          </h2>
          <h4 style={{ marginBottom: "50px", color: "#b2b2b2", fontWeight: "500", }}>
            {step.helperText}
          </h4>
            <input type={step.inputType} onChange={e => setInput(e.target.value)} style={{marginBottom: "35px"}} />
          <button onclick={step.onclick}>{step.onclickBtnText}</button>
    </div>
  )
}

1 个答案:

答案 0 :(得分:0)

稍微重构...

您的想法很优雅,因为您正在尝试重复使用步骤。 React 钩子有一些问题,它看起来很简单,但在引擎盖下有闭包,还有一些状态更新问题和一些小错误,让事情有点不正常。

这是一个修订版: https://codesandbox.io/s/objective-forest-6vp9i?file=/src/App.js

import React, { useState, useRef } from "react";

// this is your "Auth"
export default () => {
  // needed for state change/response on UI
  const [value, setValue] = useState("");

  const signIn = () => {
    alert(step1.value + " " + step2.value);
  };

  const step2 = useRef({
    stepCount: "Step 02/02",
    title: "Enter password",
    helperText:
      "If you have an account, enter your set password or if you dont't have an account enter a strong password for your acccount.",
    inputType: "password",
    onClickBtnText: "Proceed",
    value: "",
    onChange: (val) => {
      step2.value = val;
      setValue(val);
    },
    onClick: () => {
      signIn();
    }
  }).current;

  const step1 = useRef({
    stepCount: "Step 01/02",
    title: "Enter email",
    helperText:
      "Enter your email to sign in to your account. Or if you don't have an account no worries! .We will create an account for ya !",
    inputType: "email",
    onClickBtnText: "Next",
    value: "",
    onChange: (val) => {
      step1.value = val;
      setValue(val);
    },
    onClick: () => {
      setValue(step2.value);
      setStep(step2);
    }
  }).current;

  const [step, setStep] = useState(step1);

  return (
    <div style={{ display: "flex", flexFlow: "column", alignItems: "center" }}>
      <h4 style={{ marginTop: "20px", marginBottom: "10px", color: "#a3a3a3" }}>
        {step.stepCount}
      </h4>
      <h2 style={{ marginBottom: "35px" }}>{step.title}</h2>
      <h4 style={{ marginBottom: "50px", color: "#b2b2b2", fontWeight: "500" }}>
        {step.helperText}
      </h4>
      <input
        value={value}
        type={step.inputType}
        onChange={(e) => step.onChange(e.target.value)}
        style={{ marginBottom: "35px" }}
      />
      <button onClick={step.onClick}>{step.onClickBtnText}</button>
    </div>
  );
};

我保留了您的清晰想法,但只是提取了状态管理所需的位以正确刷新。 好处:您也可以将自己的价值观封装起来。

快乐编码。