redux连接组件如何知道何时重新渲染?

Joe*_*wis 65 reactjs redux react-redux

我可能遗漏了一些非常明显的东西,想要清除自己.

这是我的理解.
在一个天真的反应组件中,我们有states&props.state通过setState重新渲染更新整个组件.props大部分是只读的,更新它们没有意义.

在通过类似的方式订阅redux商店的react组件中store.subscribe(render),它显然会在每次更新商店时重新呈现.

react-redux有一个帮助器connect(),它注入部分状态树(组件感兴趣)和actionCreators props关于组件,通常通过类似的方式

const TodoListComponent = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)
Run Code Online (Sandbox Code Playgroud)

但是要理解a setState对于对TodoListComponentredux状态树更改(重新渲染)做出反应是必不可少的,我在组件文件中找不到任何statesetState相关的代码TodoList.它读起来像这样:

const TodoList = ({ todos, onTodoClick }) => (
  <ul>
    {todos.map(todo =>
      <Todo
        key={todo.id}
        {...todo}
        onClick={() => onTodoClick(todo.id)}
      />
    )}
  </ul>
)
Run Code Online (Sandbox Code Playgroud)

有人能指出我正确的方向,我错过了什么?

PS我正在关注与redux包捆绑在一起的todo list示例(https://github.com/reactjs/redux/tree/master/examples/todos/src/containers).

mar*_*son 80

connect函数生成一个订阅商店的包装器组件.调度操作时,将通知包装器组件的回调.然后它运行你的mapState函数,并从上次浅层比较此时的结果对象与上一次的结果对象(因此,如果要重写具有相同值的redux存储字段,则不会触发重新渲染).如果结果不同,那么它会将结果传递给您的"真实"组件"作为道具.

Dan Abramov connecthttps://gist.github.com/gaearon/1d19088790e70ac32ea636c025ba424e上写了一个很好的简化版本,它说明了基本思想,尽管它没有显示任何优化工作.我还链接了许多关于Redux性能的文章,讨论了一些相关的想法.

更新

React-Redux v6.0.0对连接组件如何从商店接收数据进行了一些重大的内部更改.

作为其中的一部分,我写了一篇文章,解释了connectAPI及其内部的工作方式,以及它们如何随着时间的推移而发生变化:

惯用Redux:React-Redux的历史和实现

  • 是的,那就是我:)我花了太多时间在线寻找Redux的讨论 - Reddit,HN,SO,Medium和其他各种各样的地方.乐意效劳!(另外,仅供参考,我强烈推荐Discord上的Reactiflux聊天频道.很多人都在那里闲聊并回答问题.我通常在美国东部时间在线.邀请链接在http://reactiflux.com.) (3认同)

She*_*man 9

我的答案是左边的一点点.它揭示了导致我发表这篇文章的问题.在我的情况下,似乎应用程序不重新渲染,即使它收到了新的道具.
React开发人员对这个经常被问到的问题有一个答案,如果(商店)发生了变异,那么99%的时间是反应的原因不会重新呈现.但其他1%没什么.突变不是这里的情况.


TLDR;

componentWillReceiveProps是如何state与新的同步props.

边缘案例:一旦state更新,那么应用程序重新渲染!


事实证明,如果您的应用仅state用于显示其元素,props可以更新,但state不会,因此不会重新渲染.

我有state这依赖于props从redux收到的store.我需要的数据还没有存储在商店中,所以我从中获取了数据componentDidMount,这是正确的.当我的reducer更新存储时,我得到了道具,因为我的组件是通过mapStateToProps连接的.但页面没有渲染,状态仍然是空字符串.

一个例子是用户从保存的URL加载了"编辑帖子"页面.您可以postId从网址访问,但信息store尚未存在,因此您可以获取它.页面上的项目是受控组件 - 因此您显示的所有数据都在state.

使用redux,获取数据,更新存储,并connect编辑组件,但应用程序未反映更改.仔细看,props收到了,但应用程序没有更新.state没有更新.

好吧,props会更新和传播,但state不会.你需要具体告诉state更新.

你不能这样做render(),并且componentDidMount已经完成它的周期.

componentWillReceiveProps是更新state依赖于更改prop值的属性的位置.

用法示例:

componentWillReceiveProps(nextProps){
  if (this.props.post.category !== nextProps.post.category){
    this.setState({
      title: nextProps.post.title,
      body: nextProps.post.body,
      category: nextProps.post.category,
    })
  }      
}
Run Code Online (Sandbox Code Playgroud)

我必须对这篇文章大吼大叫,这篇文章让我了解了许多其他帖子,博客和回购未能提及的解决方案.其他任何人都无法找到这个明显模糊的问题的答案,这里是:

ReactJs组件生命周期方法 - 深入研究

componentWillReceiveProps是您更新state以与props更新保持同步的地方.

一旦state更新,然后视场state 重新呈现!

  • 从"React 16.3"开始,你[应该](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props)使用`getDerivedStateFromProps`而不是`componentWillReceiveProps`.但实际上,你甚至不应该像[这里]那样做所有这些(https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html) (3认同)