javascript - Context API 和 Redux 的区别

标签 javascript reactjs

我试图找出 React Context API 和 Redux 之间的区别。 博客说它们之间的区别如下。 Context API 会在每次更新状态时提示重新渲染,并且无论如何都会重新渲染所有组件。 然而,Redux 只重新渲染更新的组件。 我已经构建了测试项目,并且发现 Context API 仅重新渲染从消费者内部渲染的组件。 但我不明白。 我认为它们的原理是相同的,我在代码中找不到差异。 我想知道为什么 Context API 理论上会重新渲染组件。

最佳答案

这是因为状态是如何封装的。在 react-redux 中,状态被封装在 store 中。当您将商店传递给 react-reedux 中的 Provider 时 - 您正在使用 Context API(请参阅 this in react-redux )但这里是关键 - redux 上下文 never变化(无论如何在 99% 的实现中)。所以 Redux 上下文的消费者永远不会像普通的 context 消费者那样重新渲染(因为上下文提供的值永远不会改变)。

那么 redux 到底是如何导致 react 组件重新渲染的呢?

一个组件 subscribe's 到通过 Redux 上下文传递的 store 和它(让我们只谈谈 useSelector 钩子(Hook) - 虽然连接 HOC 的工作方式相同) 设置它自己的 state 变量。当 redux store 的 state 更新(actions,dispatch,你知道的)时,store 调用任何带有新 state 的订阅者。如果订阅(或从状态中选择)的值与之前的值相同,则 redux 不会更新钩子(Hook)或 HOC 中的状态变量 - 查看 this file并寻找 forceRender

这与 Context API 不同,因为 Context API 的数据源(在大多数典型用例中)是 Provider 中的状态变量(或上面的 props)。每当赋予上下文的值发生变化时,消费者就会重新渲染。这与 react-redux 的工作方式根本不同,因为如上所述,赋予 react-redux 上下文 的值永不改变(是商店,记得吗?)

tldrreact-redux 中,redux 提供者提供的上下文是一个 store 并且 从不改变。在典型的非 redux 上下文 API 用例中,上下文本身提供的值会发生变化。

这可能非常令人困惑,请提出很多问题以帮助我改进答案!

编辑:您对 useDispatch 发表的评论不会导致重新渲染。这是因为 from the docs :

The dispatch function reference will be stable as long as the same store > instance is being passed to the <Provider>.

useDispatch 从不改变(只要商店不改变,99% 的时间它都不会改变,因为鼓励人们设计应用程序时只使用一个不改变的商店)

关于javascript - Context API 和 Redux 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67254562/

相关文章:

javascript - 如何创建一个以 Node 服务器作为后端的react-redux应用程序?

javascript - 如何根据页面url改变背景react js?

php - 如何使用 PHP preg_replace 和 Javascript 将 'link format' 替换为链接标记

javascript - 如何在事件处理程序上更改 React 中的特定组件

javascript - Internet Explorer 父窗口上的动态 CSS

javascript - ReactJS 中的 this.state 和 this.setstate 有什么区别?

javascript - React-intl 在 Safari v8.0.8 上禁用 react-router 的 Link 组件 onClick 事件

javascript - 如何同时使用 node-sass 和 sass-autoprefixer?

javascript - Reactjs + redux : Sharing reducers across different components

javascript - Prop 类型失败 : Invalid prop `lg` supplied to `ForwardRef(Grid)`