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

新手上路,请多包涵

我可能遗漏了一些非常明显的东西,并想澄清自己。

这是我的理解。

在一个幼稚的反应组件中,我们有 states & props 。用 setState 更新 state --- 会重新渲染整个组件。 props 大多是只读的,更新它们没有意义。

在订阅 redux 存储的反应组件中,通过类似 store.subscribe(render) ,它显然会在每次更新存储时重新呈现。

react-redux 有一个助手 connect() 注入状态树的一部分(组件感兴趣)和 actionCreators 作为 props 到组件,通常通过类似

const TodoListComponent = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

但是了解 setState 对于 TodoListComponent 对 redux 状态树更改(重新渲染)做出反应是必不可少的,我找不到任何 state 或者 setState 相关代码在 TodoList 组件文件中。它的内容如下:

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

有人可以指出我所缺少的正确方向吗?

PS 我正在关注与 redux 包 捆绑的待办事项列表示例。

原文由 Joe Lewis 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 568
2 个回答

connect 函数生成一个订阅存储的包装组件。当一个动作被调度时,包装组件的回调会被通知。然后它运行你的 mapState 函数,并 浅比较 这次的结果对象和上次的结果对象(所以如果你用相同的值 重写 一个 redux 存储字段,它不会触发重新渲染)。如果结果不同,那么它将结果作为道具传递给您的“真实”组件。

Dan Abramov 在 ( connect.js ) 上写了一个很棒的简化版本 connect 说明了基本思想,尽管它没有显示任何优化工作。我也有一些关于 Redux 性能 的文章的链接,这些文章讨论了一些相关的想法。

更新

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

作为其中的一部分,我写了一篇文章,解释了 connect API 及其内部的工作原理,以及它们如何随时间变化:

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

原文由 markerikson 发布,翻译遵循 CC BY-SA 4.0 许可协议

我的回答有点偏题。它阐明了导致我看到这篇文章的一个问题。在我的例子中,应用程序似乎没有重新渲染,即使它收到了新的道具。

React 开发人员对这个经常被问到的问题给出了一个答案,即如果 (store) 发生了变化,99% 的情况下这就是 React 不会重新渲染的原因。然而,与其他 1% 无关。这里的情况并非如此。


TLDR;

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

极端情况:一旦 state 更新,应用 程序 就会 重新渲染!


事实证明,如果您的应用仅使用 state 来显示其元素, props 可以更新,但是 state 不会重新呈现,因此。

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

这方面的一个例子是说用户从保存的 url 加载了一个“编辑帖子”页面。您可以从 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,
    })
  }
}

我必须对这篇文章大声疾呼,它启发了我许多其他帖子、博客和存储库都没有提到的解决方案。任何其他难以找到这个明显晦涩问题的答案的人,这里是:

ReactJs 组件生命周期方法——深入探讨

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

一旦 state 更新, 然后 字段取决于 state 重新 渲染!

原文由 SherylHohman 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进