Redux vs. HOC模式与useContext()和useReducer()

huangapple go评论69阅读模式
英文:

Redux vs. HOC Pattern with useContext() and useReducer()

问题

为什么要使用外部的Redux库而不是React自带的useContext()useReducer() hooks,以及Higher-Order Component (HOC)模式?

安装和导入额外的大型库,如Redux,会增加应用程序的大小并消耗更多资源。Redux本质上使用了HOC模式,利用了JavaScript的reducer模式,并使用"上下文"来跟踪全局状态。

React HOCs可以处理大型应用中由上下文提供程序创建的树状结构问题:

const App = () => {
  return (
    <Provider1>
      <Provider2>
        <Provider3>
          <Layout>
            <Main />
          </Layout>
        </Provider3>
      </Provider2>
    </Provider1>
  )
}

我尝试研究它们之间的区别和优缺点,但没有得出结论。我唯一看到使用Redux的主要优势是它有自己的浏览器扩展,Redux DevTools,对于调试和检查全局状态和HOCs非常有帮助。在您看来,使用Redux还是React的useContext()useReducer()(与HOCs和useMemo())更好,为什么?

英文:

Why would you use the external Redux library over React's own useContext() and useReducer() hooks, with the Higher-Order Component (HOC) pattern?

Installing and importing an additional, large library such as Redux increases the size of your application and consumes more resources. Redux is essentially using the HOC pattern, takes advantage of the JavaScript reducer pattern, and uses a "context" to keep tack of global state.

React HOCs take care the tree hell issue created by context providers, in large apps:

const App = () =&gt; {
  return (
    &lt;Provider1&gt;
      &lt;Provider2&gt;
        &lt;Provider3&gt;
          &lt;Layout&gt;
            &lt;Main /&gt;
          &lt;/Layout&gt;
        &lt;/Provider3&gt;
      &lt;/Provider2&gt;
    &lt;/Provider1&gt;
  )
}

I've tried to do research on the differences and pros/cons, but haven't come to a conclusion. The only major advantage I see with using Redux is that it has its own browser extension, Redux DevTools, that's helpful for debugging and inspecting global state and HOCs. In your opinion, which is better to use and why? Redux, or React useContext() and useReducer() (with HOCs and useMemo())?

答案1

得分: 4

Redux 使用上下文(context),但不用于状态值的传递,仅用于传递永不更改的存储引用。因此,Redux 的上下文永远不会引起重新渲染。之后,通过选择器和useSyncExternalStore 钩子来订阅存储更改。

仅仅使用 useReduceruseContext,无法重新创建一个高性能的状态管理库,因为通过上下文传递的值的任何更新都会重新渲染所有的消费者。你可以通过使用多个上下文来解决这个问题,但一旦你有动态添加属性或动态数量的值要高效传播,就会结束。

简而言之:使用一个状态管理库。它不一定要是 Redux,你还可以查看其他库,如 MobX、Recoil、XState、Jotai、Zustand、Valtio、HookState 或其他库 - 但上下文并不适合实际管理状态。它只是一种将很少更改的单个值传播给少数消费者的机制。

你可以在为什么 React 上下文不是"状态管理"工具(以及它为什么不能替代 Redux)中了解更多信息。

英文:

Redux uses context, but not for state value propagation, but just to pass the never-changing store reference down. As such, Redux' context will never cause any rerender. After that, subscriptions to store changes are used with selectors and the useSyncExternalStore hook.

By just using useReducer and useContext, you cannot recreate a performant state management library, as any update to any part of the value passed through the context will rerender all consumers. You can get around that by using many contexts, but ends as soon as you have dynamically added properties or a dynamic number of values you want to propagate performantly.

In short: use a state mgmt library. It doesn't need to be Redux, you can also look into other libraries as MobX, Recoil, XState, Jotai, Zustand, Valtio, HookState or others - but Context is not suited to actually manage state. It's just a mechanism to propagate a single value that rarely changes to a few consumers.

You can read more on this in Why React Context is Not a "State Management" Tool (and Why It Doesn't Replace Redux).

huangapple
  • 本文由 发表于 2023年2月10日 06:06:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75404934.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定