【ReactJS】关于 setState()你需要知道的三件事

2018-12-28  本文已影响15人  Draven_Lu

学习记录参考
state: 状态

1.不要直接修改state

// Wrong
this.state.comment = 'Hello';
// Correct
this.setState({comment: 'Hello'});

唯一能给state赋值的就是构造器

2.更新state不一定是同步,可能是异步的

React 可能会合并setState()然后进行一次更新操作
可以理解为setState()就好比是一次网络请求,什么时候有结果是不一定的。

    edit = () => {
        const { focus } = this.state//获取到上一次的state的值
        this.setState(
            {
                focus: !focus,//使用上一次的值
// focus: !this.state.focus //这样使用this.state.focus  会有问题,有可能不是最新值
            }
        )

// 下面这个写法和上面的 const { focus } = this.state  写法是一个意思
        // this.setState(
        //     preState => ({
        //         focus: !preState.focus,
        //     })
    }

官方例子如下

// Wrong   For example, this code may fail to update the counter:
this.setState({
  counter: this.state.counter + this.props.increment,
});
// Correct  
//To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:

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

// Correct  箭头函数和普通的函数都可以
this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});

state的更新操作会被合并

看个例子

//state = {
//      posts: [],
//      comments: []
//    }
// 上面的写法现在已经兼容下面的constructor写法了
  constructor(props) {
    super(props);
    this.state = {
      posts: [],
      comments: []
    };
  }

  componentDidMount() {
    fetchPosts().then(response => {
      this.setState({
        posts: response.posts
      });
    });

    fetchComments().then(response => {
      this.setState({
        comments: response.comments
      });
    });
  }

更新的state的时候,可以单独更新某一个属性,setState()会进行结果的合并,然后在render()之前,你会得到一个具有完整属性的state对象
既然更新操作有合并的特性,那么也有一个副作用
后面的值会覆盖前面的值,可能会造成状态更新的丢失

    fetchPosts().then(response => {
      this.setState({
        posts: response.posts
        comments: response.comments
      });
    });

    fetchComments().then(response => {
      this.setState({
        comments: response.comments
      });
    });
// 在执行完上述两个函数后,state中的comments值,我们无法知道是来自fetchPosts还是fetchComments

最后还有setState()还有个callBack()参数
如下,

    edit = () => {
        const { focus } = this.state
        this.setState(
            {
                focus: !focus,
            },
            () => {
                if (this.state.focus) {
                    this.inputView.focus()
                }
            },
        )
    }

callBack这种写法算是靠谱的了,嗯,目前就这么多

上一篇 下一篇

猜你喜欢

热点阅读