Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

精读《Functional setState is the future of React》 #29

Closed
fanhc019 opened this issue Aug 8, 2017 · 4 comments
Closed

精读《Functional setState is the future of React》 #29

fanhc019 opened this issue Aug 8, 2017 · 4 comments

Comments

@fanhc019
Copy link
Contributor

fanhc019 commented Aug 8, 2017

本期精读文章地址:https://medium.freecodecamp.org/functional-setstate-is-the-future-of-react-374f30401b6b

@huxiaoyun
Copy link
Contributor

占坑...

@monkingxue
Copy link

monkingxue commented Aug 8, 2017

这次的文章主要在说明一个问题 —— 为什么要使用函数式的 setState?通篇文章读下来,大概是说有两方面的原因:

效果实现层面:

React 的 setState 是异步的,并且有 Batching(批处理) 这样的一个概念。说白了就是在一段时间范围的多次 setState 会被 merge 成一个最终的改变结果,然后一起被生成 v-dom blablabla。这个其实就是常见的节流手段,本身无可厚非,但是当我多次调用 setState 去改变同一个变量时,就会出现不符合预期的行为,eg:

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

这里的本意是把 score 增加三次,但是这三次 setState 都被放在了一个 batch 中,三个 obj 会被 merge 成一个。由于这三个 obj 的 key 是相同的,所以很不幸,最终的结果只会增加一次。

如果用函数式的 setState,那上面的写法就会改为:

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

这里三次运算的过程都依赖 prevState,而正是这种依赖让 batch 能够正确 merge,让结果符合预期。

代码结构层面:

文章的最后谈到了将样式与行为分离,关于这个我的实践不是太多,就等待聚聚们的分享啦~

Fiber:

看到这篇文章的其实还想到了随着 React 16 一起出现的 Fiber reconcile,因为隐藏在 setState 背后的就是reconciliation。当然这是另外的一个话题了,以后慢慢讨论吧~

@pppluto
Copy link

pppluto commented Aug 8, 2017

函数式的 setState ,每次导致的 state 变化的行为都可以通过一个纯函数来表示,并且可以独立出行为模块来共用,对测试来说也更方便。

@ascoders
Copy link
Owner

ascoders commented Aug 10, 2017

也不是所有情况都应该使用函数式的 setState,记住一点:当 setState 中需要用到 state 时,使用函数式,其余情况使用对象更便捷。以下是比较麻烦的例子:

handleChange(value) {
  this.setState(()=> ({
    value
  }))
}

这时使用对象方式更便捷:

handleChange(value) {
  this.setState({ value })
}

至于测试,可能 setState 中测试情况很少,一般都将 action 单独拉出来做测试,组件自身的 setState 一般都是业务强相关或者内部状态,测试的意义似乎不大。

@ascoders ascoders mentioned this issue Aug 13, 2017
65 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants