也许我并不是在绕着redux转,但我看到的所有示例都没有太多地访问容器之间的状态,因此我没有看到store的太多使用.getState(),但即使要分派,也需要访问存储,对吗?
所以除了进口
在我想要获取state()或"dispatch"的每个文件中,我如何获得对该状态的访问权限,因为如果我不包括它,存储是未定义的.
也许我并不是在绕着redux转,但我看到的所有示例都没有太多地访问容器之间的状态,因此我没有看到store的太多使用.getState(),但即使要分派,也需要访问存储,对吗?
所以除了进口
在我想要获取state()或"dispatch"的每个文件中,我如何获得对该状态的访问权限,因为如果我不包括它,存储是未定义的.
一般来说,您只希望使顶级容器组件成为能够访问存储的组件——它们将把任何必要的数据或动作分派作为props 传递给其子组件.这就是"智能"组件和"哑"组件之间的区别——"智能"组件知道Redux存储/状态,而"哑"组件只是获得传递给它们的props ,不知道更大的应用程序状态.
然而,即使只是将存储区传递给容器组件也可能变得单调乏味.这就是React Redux提供一个现成组件包装整个应用程序的原因.Check it out美元.这是Provider
组件,当你用它包装整个应用程序时,你只会将应用store 传递给组件once:
import createStore from '../store';
const store = createStore()
class App extends Component {
render() {
return (
<Provider store={store}>
<MainAppContainer />
</Provider>
)
}
}
正如你在这里看到的,我有一个单独的配置文件,只针对我的store ,因为你可以做很多修改,对于任何远程复杂的应用程序,你会发现自己也在做同样的事情,比如使用compose来应用中间件.
然后剩下的任何"智能"组件(通常是包装器)都需要听store 的声音.这是使用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
数据.这意味着您只向组件公开它们在存储中所需的内容.
例如,因为ChildComponent2
作为getSomething
传递给调度操作,所以在我的onClick
中,我可以调用this.props.getSomething
,它将调用调度操作without needing any access to the store.同样,它可以继续向下传递getSomething
到另一个子组件,该组件可以调用它和/或向下传递它,循环可以无限期地继续下go .
class ChildComponent2 extends Component {
render() {
return (
<div>
<div onClick={this.props.getSomething}>Click me</div>
<NestedComponent getSomething={this.props.getSomething} />
</div>
)
}
}
Edit from the comments
虽然这与问题没有直接关系,但在 comments 中,你似乎对行动有点困惑.我并没有在这里定义动作getSomething
.相反,在Redux应用程序中,通常会将所有动作定义放在一个名为actionCreators.js
的单独文件中.它包含与操作同名的函数,并返回具有type
属性的对象以及操作所需的任何其他方法/数据.例如,下面是一个非常简单的actionCreators.js
文件示例:
export function getSomething() {
return {
type: 'GET_SOMETHING',
payload: {
something: 'Here is some data'
}
}
}
这个动作类型就是你的减速机想要知道哪个动作被触发的时候会听到的.