也许我并没有全神贯注于redux,但是我看到的所有示例并没有在容器之间真正访问过多状态,因此我没有看到store.getState()的大量使用,但是即使您想要调度,您需要访问商店,对不对?
因此,除了从“路径/到/商店/商店”导入导入商店
在每个我想要getState()或“ dispatch”的文件中,如何访问该状态,因为如果不包含它,则存储是未定义的。
通常,您只希望使顶级容器组件能够访问商店-它们会将所有必要的数据或操作分派作为其子组件的道具传递。这是“智能”组件和“哑”组件之间的区别-“智能”组件了解Redux的存储/状态,而“哑”组件只是将道具传递给它们,而对更大的应用程序状态一无所知。
但是,即使只是将商店传递到容器组件也可能变得乏味。这就是为什么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
数据。这意味着您只能将组件完全暴露给商店所需的组件。
例如,由于ChildComponent2
在as中向下传递了dispatch操作getSomething
,因此onClick
我可以调用this.props.getSomething
,它将在不需要对store的任何访问的情况下调用dispatch操作。以相同的方式,它可以继续向下传递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'
}
}
}
减速器将监听此操作类型,以了解正在触发哪个操作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句