Redux,如果我想访问数据,是否必须在所有容器中导入存储?

新手上路,请多包涵

也许我并没有把我的头放在 redux 上,但是我看到的所有示例并没有真正在容器之间访问太多状态,所以我没有看到 store.getState() 的太多用法,但即使你想调度,您需要访问商店,对吗?

所以,除了从 ‘path/to/store/store’ 导入导入存储

在我想要获取状态()或“调度”的每个文件中,我如何访问该状态,因为如果我不包含它,则存储是未定义的。

原文由 james emanon 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 466
2 个回答

通常,您只想制作可以访问商店的顶级容器组件 - 它们会将任何必要的数据或动作调度作为道具传递给它们的子组件。这就是“智能”和“哑”组件之间的区别——“智能”组件知道 Redux 存储/状态,而“哑”组件只是将 props 传递给它们,不知道更大的应用程序状态。

然而,即使只是将 store 传递给容器组件也可能变得乏味。这就是为什么 React-Redux 提供了一个开箱即用的组件来包装整个应用程序。在文档中 查看。这是 Provider 组件,当您用它包装整个应用程序时,您只需将商店传递给组件 _一次_:

 import createStore from '../store';

const store = createStore()

class App extends Component {

  render() {
    return (
      <Provider store={store}>
        <MainAppContainer />
      </Provider>
    )
  }
}

正如您在此处看到的,我有一个单独的配置文件仅用于我的商店,因为您可以进行大量修改,并且对于任何远程复杂的应用程序,您会发现自己在使用 compose 应用中间件等事情上做同样的事情。

然后你剩下的任何“智能”组件(通常是包装器)都需要听商店。这是使用 connect 方法完成的。这允许您将状态片段映射到组件属性以及将操作作为属性进行调度。

 import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as actionCreators from './actionCreators';

const mapStateToProps = function(state){
  return {
    something: state.something,
  }
}

const mapDispatchToProps = function (dispatch) {
  return bindActionCreators({
    getSomething: actionCreators.getSomething,
  }, dispatch)
}

class MainAppContainer extends Component {

    componentDidMount() {
      //now has access to data like this.props.something, which is from store
      //now has access to dispatch actions like this.props.getSomething
    }

    render() {
        //will pass down store data and dispatch actions to child components
        return (
               <div>
                   <ChildComponent1 something={this.props.something} />
                   <ChildComponent2 getSomething={this.props.getSomething} />
               </div>
        )
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(MainAppContainer)

因为您总是将调度操作和数据作为属性传递给您的子组件,所以您只需使用 this.props 引用该组件上的那些。

建立上面的例子,你会看到,因为我将 this.props.something 传递给 ChildComponent1 ,它可以访问 something 来自商店的数据有权访问 getSomething 调度操作。同样, ChildComponent2 只能访问 getSomething 调度操作,但不能访问 something 数据。这意味着您只需将组件暴露给它们在商店中所需的确切内容。

For example, because ChildComponent2 was passed down the dispatch action as getSomething , in my onClick I can call this.props.getSomething and it will call the 无需对 store 的任何访问即可 调度操作。以同样的方式,它可以继续将 getSomething 传递给另一个子组件,并且该组件可以调用它和/或传递它,并且循环可以无限期地继续。

 class ChildComponent2 extends Component {

    render() {
        return (
            <div>
                <div onClick={this.props.getSomething}>Click me</div>
                <NestedComponent getSomething={this.props.getSomething} />
            </div>
        )
    }
}

从评论中编辑

虽然这与问题没有直接关系,但在评论中,您似乎对操作有些困惑。我实际上并没有在这里定义动作 getSomething 。相反,在 Redux 应用程序中,通常将所有操作定义放在一个名为 actionCreators.js 的单独文件中。这包含与您的操作命名相同的函数,并返回一个具有 type 属性和操作所需的任何其他方法/数据的对象。例如,这是一个非常简单的示例 actionCreators.js 文件:

 export function getSomething() {
    return {
        type: 'GET_SOMETHING',
        payload: {
            something: 'Here is some data'
        }
    }
}

这个 action 类型是你的 reducer 会监听的,以知道哪个 action 被触发了。

原文由 Andy Noelker 发布,翻译遵循 CC BY-SA 4.0 许可协议

如果您使用 react-redux 包,您最终会将组件包装在 Providerstore 道具中。这将在 React 上下文中设置您的单个商店,然后从子组件中的 connect 方法访问它。 connect 方法采用两个函数(mapStateToProps 和 mapDispatchToProps),它们是您从商店获取状态和发送消息的挂钩。

在这里查看更多信息

原文由 Gabriel Isenberg 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进