【问题标题】:Redux with React - right way to share the store with componentsRedux with React - 与组件共享存储的正确方法
【发布时间】:2016-04-15 04:31:12
【问题描述】:

来自 Redux 的 store 服务最终被 React 应用程序中的各种组件使用。它所暴露的方法(如 dispatch、getState 和 subscribe)被各种组件(如容器或展示)使用。

我认为传递此存储服务的方法是一个重要的设计决策。我看到了两种方法,它们是:

1) 通过将 store 作为 prop 传递给所有嵌套级别的每个组件。这不是推荐的。

2) 使用像 react-redux 这样的工具,它在上下文的帮助下,可以在任何需要的地方使用 store(准确地说是 state 和 dispatch)。

我的问题是:为什么不直接在需要的地方导入商店。对于基于 SPA 的 React 应用程序,store 将是一个单例。嵌套在任何级别的组件都可以简单地导入商店。为什么我们应该采用上述两种方法中的任何一种?

对于任何嵌套级别的组件:我们可以这样做

import store from  "path/to/store";

let MyComponent = () => {
    let state = store.getState();

    return (
        <div onClick={() => {
            store.dispatch({
                type: "SOME_EVENT",
                payload: store.somedata
            });
        }}>{state.dataINeedHere}</div>
    );
};

export default MyComponent;

而不是

import { connect } from "react-redux";

let MyComponent = ({somedata, onMyAction}) => {
    let state = store.getState();

    return (
        <div onClick={() => {
            onMyAction(somedata);
        }}>{somedata}</div>
    );
};

const mapStateToProps = (state) => {
  return {
    somedata: state.somedata
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onMyAction: (input) => {
      dispatch({
          type: "SOME_EVENT",
          payload: input
      });
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);

【问题讨论】:

  • 在你的“我们可以这样做”的例子中,当某些状态发生变化时,什么会导致你的组件重新渲染?
  • 我会在顶层订阅状态更改并触发重新渲染
  • 你研究过 mobx / mobx-react 吗?听起来像你描述的那样。

标签: reactjs redux react-redux


【解决方案1】:

Redux FAQ 涵盖了这个问题,http://redux.js.org/docs/FAQ.html#store-setup-multiple-stores

总结:虽然您可以直接导入商店,但您将代码绑定到该商店实现,这使得它的可重用性和测试难度降低。理想情况下,您自己的代码实际上都不会直接引用商店。连接的组件、中间件和 thunked 动作创建者都通过依赖注入接收相关的 dispatchgetState 函数引用,使其可重用并允许轻松模拟行为以进行测试。

【讨论】:

    【解决方案2】:

    考虑当您有第二个 MyComponent 时会发生什么,它管理来自商店不同部分的数据。您的选择是准确地告诉每个人如何访问/更新其数据:

    <Container>
       <MyComponent path="/a/b/c" />
       <MyComponent path="/a/b/d" />
    </Container>
    

    或者您可以只授予每个访问权限:

    <Container>
       <!-- context /a/b was passed to Container -->
       <MyComponent data={c} onUpdate={update(c)} />
       <MyComponent data={d} onUpdate={update(d)} />
    </Container>
    

    后者使 MyComponent 更加简单和灵活。

    【讨论】:

      猜你喜欢
      • 2018-01-21
      • 1970-01-01
      • 2019-06-27
      • 2021-12-06
      • 2017-01-14
      • 1970-01-01
      • 1970-01-01
      • 2018-12-12
      • 2019-05-15
      相关资源
      最近更新 更多