与 Redux 反应? “上下文”问题呢?
Posted
技术标签:
【中文标题】与 Redux 反应? “上下文”问题呢?【英文标题】:React with Redux? What about the 'context' issue? 【发布时间】:2016-07-25 12:16:58 【问题描述】:我通常在 Stack 上发布与代码相关的内容,但这更多是关于社区的一般想法的问题。
似乎有很多人提倡使用 Redux 和 React 来管理数据/状态,但是在阅读和学习两者时,我遇到了一些看起来不太正确的东西。
Redux
在此页面底部:http://redux.js.org/docs/basics/UsageWithReact.html(传递商店)它建议使用 React 'Context' 的“魔术”。
一种选择是将它作为道具传递给每个容器组件。然而,它变得乏味,因为您甚至必须通过展示组件来连接存储,因为它们恰好在组件树的深处渲染了一个容器。
我们推荐的选项是使用一个特殊的 React Redux 组件调用来神奇地使 store 可用于所有容器组件...
反应
在 React Context 页面 (https://facebook.github.io/react/docs/context.html) 顶部有一个警告:
上下文是一项高级且实验性的功能。 API 可能会在未来的版本中发生变化。
然后在底部:
正如在编写清晰的代码时最好避免使用全局变量一样,您应该在大多数情况下避免使用上下文...
不要使用上下文通过组件传递模型数据。通过树显式地线程化您的数据更容易理解......
所以...
Redux 建议使用 React 'Context' 功能,而不是通过'props' 将store
向下传递给每个组件。而 React 建议相反。
另外,似乎 Dan Abramov(Redux 的创建者)现在为 Facebook(React 的创建者)工作,只是为了让我更加困惑。
我没看错吗..? 目前对此问题的普遍共识是什么?【问题讨论】:
啊,这是一个很好的问题,我也很想听听其他人的观点!由于讨论方面,我有点担心它会被关闭。我真的希望不会。 【参考方案1】:我不知道其他人,但我更喜欢使用 react-redux 的 connect 装饰器来包装我的组件,这样只有我需要的 store 中的 props 才会传递到我的组件中。这在某种意义上证明了使用上下文是合理的,因为 我 没有使用它(而且我知道,作为一项规则,我负责的任何代码都不会使用它)。
当我测试我的组件时,我会测试未包装的组件。因为 react-redux 只通过了我在那个组件上需要的 props,所以我现在确切地知道我在编写测试时需要什么 props。
我想重点是,我从来没有在我的代码中看到上下文这个词,我不使用它,所以在某种程度上,它不会影响我!这并没有说明 Facebook 的“实验性”警告。如果上下文消失了,在 Redux 更新之前,我会和其他人一样被搞砸。
【讨论】:
有趣...我明白你所说的“react-redux”是什么意思,使用Provider
和connect
抽象出所有上下文内容。我猜 Dan Abramov 现在在 FB,你希望如果 Context 改变了 Redux 并且 'react-redux' 会被更新......但不能保证,而且 FB 的“实验性”警告仍然有目共睹。
我当然希望如果 FB 不将 react-redux 保留在循环中,以防上下文发生任何事情,一个比我更熟悉 redux 的开源贡献者会这样做;如果没有,我会想办法自己做!
我通过 Twitter 向 Dan 询问了他的想法......很好的答案,大致相同......使用使用 Context 的库,不要直接使用它。【参考方案2】:
上下文是一项高级功能,可能会发生变化。在某些情况下,它的便利性超过了它的缺点,因此一些库(如 React Redux 和 React Router)尽管具有实验性质,但仍选择依赖它。
这里的重要部分是 libraries 这个词。如果上下文改变了它的行为,我们作为库作者将需要调整。但是,只要库不要求您直接使用上下文 API,您作为用户就不必担心对其进行更改。
React Redux 在内部使用上下文,但它没有在公共 API 中公开这一事实。所以你应该觉得通过 React Redux 使用上下文比直接使用上下文更安全,因为如果它发生变化,更新代码的负担将落在 React Redux 而不是你身上。
React Redux 最终仍然支持始终将 store 作为 prop 传递,因此如果您想完全避免上下文,您可以选择。但是我会说这是不切实际的。
TLDR:除非您真的知道自己在做什么,否则请避免直接使用上下文。使用恰好在内部依赖上下文的库是相对安全的。
【讨论】:
丹说得好。风险在于,如果 React 在未来的版本中完全删除上下文,它可能需要返工来更新任何现有的 Redux 应用程序。 Redux 不太可能保护用户免受此类更改的影响。鉴于您现在使用 Facebook,好消息是,如果上下文消失,我希望您会提前收到大量通知。 React 不会删除上下文。我的意思是,这在技术上是可行的,但它存在的全部原因是因为 FB 内部的许多产品都需要它。因此,除非有等效的解决方案,否则它不会消失。但它的确切 API 可能会发生变化,这是我们保护用户的原因。 另一个重要的注意事项是 React 计划在未来更多地而不是更少地使用上下文。我们认为它可能对样式、动画、手势处理等有用。 有趣的是,当你获得 React 组件库(例如 Material-ui)时,它们自然不会构成你的应用程序状态模型的一部分,但仍然只是 React 组件树同样,维护自己的状态模型和数据流与“主”应用程序分开的相同要求。因此,他们正在利用上下文功能作为(对他们而言)将数据向下传递到其子层级的唯一手段。 @DanAbramov 新的上下文 API 怎么样?还是不推荐使用吗?【参考方案3】:有一个 npm 模块可以很容易地将 redux 添加到 react 上下文中
https://github.com/jamrizzi/redux-context-provider
https://www.npmjs.com/package/redux-context-provider
import React, Component from 'react';
import ReduxContextProvider from 'redux-context-provider';
import createStore from './createStore';
import actions from './actions';
import Routes from './routes';
export default class App extends Component
render()
return (
<ReduxContextProvider store=store actions=actions>
<Routes />
</ReduxContextProvider>
);
【讨论】:
以上是关于与 Redux 反应? “上下文”问题呢?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Context API 与 Redux 有性能优势吗?