React中的handleClick函数如何检索以前的状态值?

时间:2020-04-21 14:23:39

标签: javascript reactjs

codepen将按钮值从true切换到false

除了此handleClick函数的工作方式之外,我还了解这一点:

 handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

有人可以对此进行细分,并用简单的术语来解释该函数如何检索isToggleOn bool值吗?

我知道我们不能直接在!this.state.isToggleOn中使用setState,但是有人可以简单地解释一下为什么在这种情况下,对于React新手来说,这个handleClick函数更可靠吗? / p>

在这里调用handleClick函数:

render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );

3 个答案:

答案 0 :(得分:1)

setState文档中:

第一个参数是带有签名的更新程序函数

(state, props) => stateChange

state是对应用更改时组件状态的引用。

在您的示例中,prevState被重命名为state,它包含状态中的所有分配,包括isToggleOn

您也可以仅在this.state函数中阅读setStateprevState模式用于传达这是旧状态/当前状态(正在更改的状态)。

setState docs

答案 1 :(得分:0)

在这种情况下,您实际上可以同时使用这两种方法,因为它非常简单,您可以从render函数调用setState。在课堂上,很难找到一个this.setState({oldState:this.state.oldState})有问题的地方。 相反,如果您使用功能组件或钩子,则会经常看到此问题。

JS不是面向对象的!

要了解这一点,您必须首先考虑js 不是一种面向对象的语言。 React试图模拟它。基本上,当您更改状态时,包含状态的类将再次被调用,以尝试仅运行更改的代码。在您的情况下,调用handleClick时,render函数会因为状态更改而被触发!

对此进行说明,handleClick不仅仅是一个功能!这也是该类的属性。 React试图了解是否应该根据它们使用的值“重新声明”这些函数。

良好做法

在您编写isToggleOn: !prevState.isToggleOn的情况下,该函数是独立的。它不需要类的任何其他属性(setState的一部分,它可以使用不同的模式),因此在状态更改后,react引擎不必再次设置该函数。

错误的练习(有时写起来容易得多)

相反,如果您使用isToggleOn: !this.state.isToggleOn,则handleClick函数依赖于this.state,因此每次更改时,React引擎都必须通过以下方式“重新声明”该函数:将this.state替换为{isToggleOn:...}

如何重新创建该图案

function myRandom(property){
  //Kind of private Variable
  let hiddenVar=Math.random();
  return property(hiddenVar);
}

//Let's say here the Math class is unreachable while myRandom is.
myRandom((num)=>{
  console.log(num);//This ac
})

答案 2 :(得分:-3)

也许只是check the docs

setState()的第二个参数是可选的回调函数,将在setState完成并重新渲染组件后执行。通常,我们建议改将componentDidUpdate()用于此类逻辑。

本质上,您是在函数中获取状态的前一个实例,然后对状态进行更改并返回它。此新状态将被保存并导致您的组件重新呈现。

如果您使用功能组件,则可以不必在此处传递回调,并且可以执行以下操作:

function MyComponent() {
  const [on, setOn] = React.useState(false)

  return (
    <button onClick={() => setOn(!on)}>
      {on? 'ON' : 'OFF'}
    </button>
  );
}