使用回调函数和理解箭头符号的正确方法

时间:2018-03-21 19:40:37

标签: javascript reactjs arrow-functions

在我的increaseCount方法中,我有3种不同的增加计数的方法。我认为第一种方法可以使用两次但它不起作用,因为它似乎在回调中合并了setState。使用回调函数的正确方法是什么?为什么箭头符号有效? prevState.count是如何定义的?永远不会设置为0

import React from "react";
import { render } from "react-dom";

const styles = {
  fontFamily: "sans-serif",
  textAlign: "center"
};

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  increaseCount() {
    console.log(this);
    this.setState({ count: this.state.count }, function() {
      this.setState({ count: this.state.count + 1 });
    });

    this.setState({ count: this.state.count + 1 });

    this.setState(prevState=>({ count: prevState.count + 1 }));
  }

  render() {
    return (
      <div style={styles}>
        <div>
          <button onClick={() => this.increaseCount()}>Increase</button>
        </div>
        <h2>{this.state.count}</h2>
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

3 个答案:

答案 0 :(得分:4)

据我所知,只有你的第三种方法是增加状态值的正确方法。经历你的尝试:

this.setState({ count: this.state.count }, function() {
  this.setState({ count: this.state.count + 1 });
});

此代码段是冗余的(您将计数设置为相同的值),然后当状态更改完成后,您可以通过向this.state.count添加1来增加计数。虽然这很好,但你可以在开始时做到这一点(如你的下一个片段)。

下一步:

this.setState({ count: this.state.count + 1 });

更好,但setState方法是异步的,因此实际状态更改将在以后发生。这意味着这在大多数情况下都有效,但是如果你要调用它两次,就不会增加2,因为this.state.count在第二次调用时还没有更新

最后,你的最后一次尝试看起来很完美:

this.setState(prevState=>({ count: prevState.count + 1 }));

这使用函数setState语法,其中react将为您的回调函数提供当前状态,并且您应该读取它并返回所需的新状态。使用这种风格,您可以将它调用两次(或任意多次),每次调用都会正确地增加计数。

解决您的其他一些问题:

  

似乎在回调中合并了setState。

正确。从以下链接的文档:

  

React可以将多个setState()调用批处理为单个更新以提高性能。

  

使用回调函数的正确方法是什么?为什么箭头符号有效?

功能setState是一个新的反应功能。箭头函数很好但不是必需的(除非你在回调中访问this)。来自documentation here

  

要修复它,请使用接受函数的第二种形式的setState()   而不是一个对象。 该功能将获得之前的状态   作为第一个参数,以及应用更新时的道具   作为第二个论点:

// Correct
this.setState((prevState, props) => ({
    counter: prevState.counter + props.increment
}));
     

我们使用了上面的箭头功能,但它也适用于常规功能:

// Correct
this.setState(function(prevState, props) {
    return {
        counter: prevState.counter + props.increment
    };
});
  

如何定义prevState.count?永远不会设置为0

在构造函数中将其设置为零。这一行:

this.state = {
  count: 0
};

是最初的设定。从那时起,当前状态(无论它是什么)通过了setState回调函数。

对不起墙,这个答案在我知道之前就失控了。希望如果我错过了这一点或者还有更多问题,那么LMK会有所帮助

答案 1 :(得分:1)

  • increaseCount函数需要是箭头函数,因为您没有绑定它。
  • setState是异步函数,调用后不会执行不正确的操作。所以第二个setState将无法正确执行。一般来说,对于单个事件,setState最好一次。 Link to doc
  • this.setState(function() {})有效,但我没有在文档的任何位置看到this.setState({ count: this.state.count }, function() {})

要根据您的代码获得预期结果,这是正确的模式:

increaseCount = () => {
  let countBuffer = this.state.count;
  countBuffer++;
  countBuffer++;
  countBuffer++;

  this.setState(prevState => ({ count: countBuffer }));
}

这应该可行,但它不是首选方法,因为它需要多次不必要的渲染:

increaseCount = async () => {
  await this.setState(function(){ return { count: this.state.count + 1 } });
  await this.setState({ count: this.state.count + 1 });
  this.setState(prevState=>({ count: prevState.count + 1 }));
}

答案 2 :(得分:0)

你应该bind你的回调函数才能使用&#39;这个&#39;

你的构造函数应该如下所示:

constructor(props) {
    super(props);
    this.state = {
      count: 0
    };

    this.increaseCount = this.increaseCount.bind(this)
  }

修改

并且您的inreaseCount函数应如下所示:

increaseCount() {
    console.log(this);
    this.setState(prevState=> ({ count: prevState.count + 1 })) ;
  }