资讯专栏INFORMATION COLUMN

使用React.setState需要注意的三点

instein / 1180人阅读

摘要:而不是在方法中在通过来获取使用回调函数方法接收一个作为回调函数。这样子直接输出,回调函数,对比如果默认为输入的结果是和渲染无关的状态尽量不要放在中来管理通常中只来管理和渲染有关的状态,从而保证改变的状态都是和渲染有关的状态。

原文: https://medium.com/@mweststra...
作者: Michel Weststrate

前言

这篇文章原标题是3 Reasons why I stopped using React.setState,但是我对原文作者提出的论点不是很感冒,但是作者提出的三点对React新手来说是很容易忽略的地方,所以我在这里只提出部分内容,而且把标题改为使用React.setState需要注意的三点

正文

React新手来说,使用setState是一件很复杂的事情。即使是熟练的React开发,也很有可能因为React的一些机制而产生一些bug,比如下面这个例子:

文档中也说明了当使用setState的时候,需要注意什么问题:

注意:
绝对不要 直接改变this.state,因为之后调用setState()可能会替换掉你做的改变。把this.state当做是不可变的。

setState()不会立刻改变this.state,而是创建一个即将处理的state转变。在调用该方法之后访问this.state可能会返回现有的值。

setState的调用没有任何同步性的保证,并且调用可能会为了性能收益批量执行。

setState()将总是触发一次重绘,除非在shouldComponentUpdate()中实现了条件渲染逻辑。如果可变对象被使用了,但又不能在shouldComponentUpdate()中实现这种逻辑,仅在新state和之前的state存在差异的时候调用setState()可以避免不必要的重新渲染。

总结出来,当使用setState的时候,有三个问题需要注意:

1. setState是异步的(译者注:不保证同步的)

很多开发刚开始没有注意到setState是异步的。如果你修改一些state,然后直接查看它,你会看到之前的state。这是setState中最容易出错的地方。 setState这个词看起来并不像是异步的,所以如果你不假思索的用它,可能会造成bugs。下面这个例子很好的展示了这个问题:

class Select extends React.Component {
  constructor(props, context) {
    super(props, context)
    this.state = {
      selection: props.values[0]
    };
  }
  
  render() {
    return (
      
    {this.props.values.map(value =>
  • this.onSelect(value)} > {value}
  • )}
) } onSelect(value) { this.setState({ selection: value }) this.fireOnSelect() } onKeyDown = (e) => { const {values} = this.props const idx = values.indexOf(this.state.selection) if (e.keyCode === 38 && idx > 0) { /* up */ this.setState({ selection: values[idx - 1] }) } else if (e.keyCode === 40 && idx < values.length -1) { /* down */ this.setState({ selection: values[idx + 1] }) } this.fireOnSelect() } fireOnSelect() { if (typeof this.props.onSelect === "function") this.props.onSelect(this.state.selection) /* not what you expected..*/ } } ReactDOM.render(