也许我并没有围绕redux,但我见过的所有例子都没有真正在容器之间访问状态太多,所以我没有看到很多用于store.getState()的东西,但即使你想要派遣,你需要访问商店,对吧?
所以,除了从'path/to/store/store'导入import store之外
在我想要getState()或"dispatch"的每个文件中,如何访问该状态,因为如果我不包含它,则存储未定义.
And*_*ker 80
通常,您只想制作能够访问商店的顶级容器组件 - 它们会将任何必要的数据或操作调度作为道具传递给其子组件.这是"智能"和"哑"组件之间的区别 - "智能"组件了解Redux存储/状态,而"哑"组件只是将道具传递给他们并且不知道更大的应用程序状态.
然而,即使只是将商店传递给容器组件也会变得乏味.这就是为什么React-Redux提供了一个包装整个应用程序的开箱即用的组件.在文档中查看.这是Provider
组件,当您用它包装整个应用程序时,您只需将商店传递给组件一次:
import createStore from '../store';
const store = createStore()
class App extends Component {
render() {
return (
<Provider store={store}>
<MainAppContainer />
</Provider>
)
}
}
Run Code Online (Sandbox Code Playgroud)
正如你在这里看到的,我有一个单独的配置文件只是为了我的商店,因为你可以做很多修改,对于任何远程复杂的应用程序,你会发现自己也在做同样的事情,比如使用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)
Run Code Online (Sandbox Code Playgroud)
因为您始终将调度操作和数据作为属性传递给子组件,所以您只需引用该组件上的那些操作和数据this.props
.
基于上面的示例,您将看到,因为我传递this.props.something
给ChildComponent1
它,它可以访问something
商店中的数据,但它无权访问getSomething
调度操作.同样,ChildComponent2
只能访问getSomething
调度操作而不能访问something
数据.这意味着您只能将组件暴露给他们所需的商店.
例如,因为ChildComponent2
传递了调度操作,因为getSomething
在我onClick
可以调用this.props.getSomething
它并且它将调用调度操作而不需要任何访问存储.以同样的方式,它可以继续传递getSomething
给另一个子组件,该组件可以调用它和/或将其传递下去,并且循环可以无限期地继续.
class ChildComponent2 extends Component {
render() {
return (
<div>
<div onClick={this.props.getSomething}>Click me</div>
<NestedComponent getSomething={this.props.getSomething} />
</div>
)
}
}
Run Code Online (Sandbox Code Playgroud)
从评论中编辑
虽然这与问题没有直接关系,但在评论中你似乎对行动有点困惑.我实际上并没有在getSomething
这里定义动作.相反,在Redux应用程序中通常会将所有操作定义放在一个名为的单独文件中actionCreators.js
.这包含与您的操作命名相同的函数,并返回具有type
属性的对象以及操作所需的任何其他方法/数据.例如,这是一个非常简单的示例actionCreators.js
文件:
export function getSomething() {
return {
type: 'GET_SOMETHING',
payload: {
something: 'Here is some data'
}
}
}
Run Code Online (Sandbox Code Playgroud)
此操作类型是您的reducer将侦听以了解正在触发的操作的操作类型.
Gab*_*erg 15
如果您使用该react-redux
包装,您将最终将您的组件包装在Provider
一个store
支柱中.这将在React上下文中设置您的单个存储,然后从connect
子组件中的方法访问该上下文.该connect
方法有两个函数(mapStateToProps和mapDispatchToProps),它们是从商店获取状态和调度消息的钩子.