小编典典

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

reactjs

也许我并没有全神贯注于redux,但是我所看到的所有示例并没有在容器之间真正访问过多的状态,因此我并没有看到store.getState()的大量使用,但是即使您想要派遣,您需要进入商店,对不对?

因此,除了从“路径/到/商店/商店”导入导入商店

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


阅读 157

收藏
2020-07-22

共1个答案

小编典典

通常,您只希望使那些可以访问商店的顶级容器组件成为可能-
它们会将所有必要的数据或操作分派作为其子组件的道具传递。这是“智能”和“哑”组件之间的区别-“智能”组件了解Redux的存储/状态,而“哑”组件只是将prop传递给它们,而对更大的应用程序状态一无所知。

但是,即使只是将商店传递到容器组件也可能变得乏味。这就是为什么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.somethingChildComponent1,因此它可以访问something存储中的数据,但不能访问getSomething调度操作。同样,ChildComponent2只能访问getSomething调度操作,而不能访问something数据。这意味着您只能将组件完全暴露给商店所需的组件。

例如,由于ChildComponent2作为传递给了调度动作getSomething,在我中,onClick我可以调用this.props.getSomething,它将在
不需要对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'
        }
    }
}

减速器将监听此操作类型,以了解正在触发哪个操作。

2020-07-22