如何使用react钩子useState在表单上显示/隐藏一些警报

时间:2019-12-18 04:34:37

标签: javascript reactjs react-hooks

我有一个要进行基本验证检查的表格。我想检查除复选框外,是否有任何值是empy,但我们只能从一个验证开始。我以为我可以使用useState钩子,但是它总是在第一次提交时(将值填满时)将默认值设置为true,即使在输入值填满时也将其设置为true。

const [nameVal, setNameVal] = useState(false);


 const submitForm = async (e) => {
  e.preventDefault();


  //console.log(e.target.name.value);

  if(e.target.name.value === ""){
    setNameVal(false);
    console.log(nameVal);
  }
  else{
    setNameVal(true);
    console.log(nameVal);
  }

我如何让console.log(nameVal)在第一次提交表单并填写true时显示target.name.value。当前,它是第一次false,然后每次是true。因此,除了最初的点击之外,一切似乎都可以按照我的意愿进行。提前谢谢

2 个答案:

答案 0 :(得分:3)

让我们回顾一下useState的工作原理

执行此操作

const [nameVal, setNameVal] = useState(false);

您正在创建一个变量(初始值为false)和一个函数。这意味着在您的处理程序中(假设您正确填写了一个值)

 const submitForm = async (e) => {
  e.preventDefault();
  if(e.target.name.value === ""){
    setNameVal(false);
    console.log(nameVal); // --> here it will log true

您将看到已记录的true,因为nameVal是上方的变量(在useState行中)。当您运行setNameVal(false)时,它基本上会继续执行您的代码,完成后,它会在React中触发对帐算法,这将导致新的渲染。这次(第二次),这条线在运行

const [nameVal, setNameVal] = useState(false);

nameVal将为真。这是因为初始值仅用于第一个渲染。,并且由于它知道状态的值已更改,这要归功于您调用setXXX函数来更新为新状态

您需要将功能组件视为状态和道具的函数,并且对状态所做的所有更改的每个更改,都将在下一个渲染周期中渲染新的输出。因此,这意味着-每个渲染器都有自己的道具和状态

(不过,这不是我的,请阅读Dan Abramov的这篇精彩文章,其中还谈到了useEffect https://overreacted.io/a-complete-guide-to-useeffect/

======================

关于您的问题,如何“切换”某些消息以显示useState?一般形式可能是

const [showMessage, setShowMessage] = useState(false)

const someEvent = () => {
  // do stuff
  if (someCondition) {
       setShowMessage(true)
  }
}

// more stuff

return (
   <div>
       { showMessage && <span>I am a message!</span>}
        <Foo onChange={someEvent} />
   </div>
)

说明:

  • 初始渲染。 showMessage是错误的,因此{ showMessage && <span>I am a message!</span>}将返回false(这使得React无法呈现任何内容)
  • 当某个事件触发我们的函数处理程序时,我们会将showMessage设置为true。
  • 在下一次渲染(对帐算法检测到状态变化并激发新的渲染)时,我们看到showMessage为真,因此span得以渲染

答案 1 :(得分:0)

在初始状态下,您的namevalue为false,就像这样:

const [nameVal, setNameVal] = useState(false); 我建议您像这样设置nameVal的新状态:

setNameVal(!nameVal);