【问题标题】:Re-rendering of connect()ed component based on mapStateToProps output基于 mapStateToProps 输出重新渲染 connect()ed 组件
【发布时间】:2016-07-04 17:32:20
【问题描述】:

在基于 React + Redux 的项目中,我有一个 connect()ed 组件,它通过 API 获取检查用户权限。获取的权限存储在 Redux 存储中。

该组件基本上看起来像<Can check="...">...</Can>,它与我们的 API(通过 Redux 操作)对话以解决检查。如果授予权限,则呈现this.props.children,否则呈现null。

为此,mapStateToProps() 根据存储中的授权数据计算 passes 属性,该属性在 <Can />s render() 方法中检查。我利用mapStateToProps() 的ownProps 参数来获取“要检查的内容”并计算passes 标志。

有一些缓存正在进行,所以我不会在每个组件安装上重新获取,它基本上可以工作。但是,有时,当 passes 属性更新为 true 时,组件不会重新渲染(但是它会在导航离开后渲染 - 使用反应路由器 - 并再次返回,所以基本上如果组件被重新安装)。

如果mapStateToProps() 的输出发生变化,connect()ed 组件是否会重新渲染? react-redux 的 connect() 的文档是这样说的:

如果将 ownProps 指定为第二个参数,则其值将是传递给组件的 props,并且每当组件接收到新的 props 时都会重新调用 mapStateToProps。

这是否意味着传入ownProps 会将渲染更改为仅在道具更改时或以其他方式重新渲染?我如何理解关于从mapStateToProps() 中记忆/返回函数的注释,或者这甚至不相关?

谢谢

【问题讨论】:

    标签: javascript reactjs redux


    【解决方案1】:

    如果 mapStateToProps() 的输出发生变化,是否会重新渲染 connect()ed 组件? react-redux 的 connect() 的文档是这样说的:

    函数的输出不能自行改变。必须首先触发此功能才能重新评估。

    如果 Redux 状态发生变化,mapStateToProps 会重新评估。

    如果从父组件接收到的 props 不相等(已更改)并且您使用 ownProps 参数,mapStateToProps 也会重新评估。

    如果 mapStateToProps 返回与其上次调用相同的值,则 React Redux 将跳过渲染。如果它返回浅不相等的值,则包装的组件将被重新渲染。假设mapStateToProps本身就是一个纯函数。

    但有时,当 pass 属性更新为 true 时,组件不会重新渲染

    请创建一个最小项目来重现此内容并使用相关代码示例提交问题。

    我如何理解有关从 mapStateToProps() 存储/返回函数的注释,或者这甚至不相关?

    不相关。

    【讨论】:

    • 感谢您这么快回答。在提交问题之前,我会再次检查并确保减速器或选择器逻辑中没有任何错误。浅层的相等检查可能是个问题。
    • 作为对connect() 文档的快速建议,也许将措辞更改为 [...] 并且 mapStateToProps 将在组件收到新道具时*另外*重新调用。
    【解决方案2】:

    这里有几件事要知道:

    1. connect 会将最后一次mapState 调用的输出与当前mapState 调用的输出进行浅比较。如果没有任何改变,它不会重新渲染被包装的组件。
    2. 默认情况下,connect 只会在商店通知订阅者时运行mapState。但是,如果您的 mapState 函数被声明为采用 两个 参数,connect 将传入包装组件的 props 作为第二个参数,允许您执行 state.somePerItemData[ownProps.itemId] 之类的操作。然后它还会在传入的道具不同时调用mapState,因为这可能会影响mapState的输出。
    3. 重新选择的默认记忆仅保留每个选择器函数的单个缓存值。如果您有一个组件被多次实例化,并且所有实例都共享同一个选择器函数实例,那么选择器的记忆可能不会按照您想要的方式工作,因为每个组件实例可能使用不同的输入调用它(例如他们自己的道具)。因此,作为一项非常高级的优化,您实际上可以将工厂函数作为 mapState 参数传递,这可以为每个组件实例创建一个唯一的选择器函数实例。

    说了这么多,对于您关于未更新组件的实际问题,恐怕我没有具体的答案。我可能需要更详细地查看代码。

    【讨论】:

    • 感谢您的澄清。我们不使用重新选择,但我可以看到您描述的问题。我错过了这样一个事实,即在 mapState 中使用 ownProps 会导致对 mapState 的额外重新评估,而不是排他性的。
    猜你喜欢
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 2018-12-12
    • 1970-01-01
    相关资源
    最近更新 更多