reactjs – 如何在Redux中为每个实例创建一个商店?
有时,在Redux应用程序中为每个实例创建一个商店会很有用. Redux的创建者自己创建了一个Gist,描述了如何实现这个目标:
https://gist.github.com/gaearon/eeee2f619620ab7b55673a4ee2bf8400
我已经在Gist中提出了这个问题,但我认为StackOverflow对于这个问题来说会更好: 我想知道如何将操作分派给组件自己的特殊商店?有没有办法访问< Provider />的store-prop.对于每个< SubApp /> (和他们的孩子组成部分)? 例如:我有一些API类在从远程服务器获取数据后调用dispatch.但由于我无法导入“普通”商店,处理自定义商店以使其可用于其他类/文件/服务的最佳方式是什么? 更新1 所以我得到了它的工作,但我认为这是一种非常肮脏的方式(请注意UGLY?代码中的注释): 提供者: 通过在构造函数中创建商店来为每个实例创建一个商店: export default class OffersGridProvider extends React.Component { constructor(props) { super(props) this.store = createStore(reducers); } render() { return ( <Provider store={this.store}> <OffersGridContainer offers={this.props.offers} /> </Provider> ); } } 容器: 提供者将此商店的调度方法注入我的OffersGridContainer,我可以使用该方法将操作分派给此实例的商店: class OffersGridContainer extends React.Component { componentDidMount() { // UGLY??? const { dispatch } = this.props; let destinationIds = []; this.props.offers.forEach((offer) => { offer.to.forEach((destination) => { destinationIds.push(destination.destination); }); }); // MORE UGLY??? destinationsApi.getDestinations(dispatch,destinationIds); } render() { return ( <OffersGridLayout destinations={this.props.destinations} /> ); } } const mapStateToProps = function(store) { return { destinations: store.offersGridState.destinations }; } export default connect(mapStateToProps)(OffersGridContainer); API方法: 只需使用我作为参数传递给我的API方法的dispatch方法: export function getDestinations(dispatch,ids) { const url = $('meta[name="site-url"]').attr('content'); const filter = ids.map((id) => { return `filter[post__in][]=${id}`; }).join('&'); return axios.get(`${url}/wp-json/wp/v2/destinations?filter[posts_per_page]=-1&${filter}`) .then(response => { dispatch(getOffersGridSuccess(response.data)); return response; }); } 更新2 刚收到评论中关于mapDispatchToProps的提示,所以我的Container现在看起来像这样: class OffersGridContainer extends React.Component { componentDidMount() { let destinationIds = []; this.props.offers.forEach((offer) => { offer.to.forEach((destination) => { destinationIds.push(destination.destination); }); }); this.props.getDestinations(destinationIds); } render() { return ( <OffersGridLayout destinations={this.props.destinations} /> ); } } const mapStateToProps = function(store) { return { destinations: store.offersGridState.destinations }; } const mapDispatchToProps = function(dispatch) { return { getDestinations: function(ids) { return destinationsApi.getDestinations(dispatch,ids); } } } export default connect(mapStateToProps,mapDispatchToProps)(OffersGridContainer); 更新3(最终答案) 现在一切正常!这是代码: 提供者: export default class OffersGridProvider extends React.Component { constructor(props) { super(props) this.store = createStore(reducers,applyMiddleware(thunk)); } render() { return ( <Provider store={this.store}> <OffersGridContainer offers={this.props.offers} /> </Provider> ); } } 容器: class OffersGridContainer extends React.Component { componentDidMount() { const destinationIds = this.props.offers.reduce((acc,offer) => { return [...acc,...offer.to.map(d => d.destination)]; },[]); this.props.getDestinations(destinationIds); } render() { return ( <OffersGridLayout destinations={this.props.destinations} /> ); } } const mapStateToProps = function(store) { return { destinations: store.offersGridState.destinations }; } const mapDispatchToProps = function(dispatch) { return { getDestinations: function(ids) { return dispatch(destinationsApi.getDestinations(ids)); } } } export default connect(mapStateToProps,mapDispatchToProps)(OffersGridContainer); API方法: export function getDestinations(ids) { return function(dispatch) { const url = $('meta[name="site-url"]').attr('content'); const filter = ids.map((id) => { return `filter[post__in][]=${id}`; }).join('&'); return axios.get(`${url}/wp-json/wp/v2/destinations?filter[posts_per_page]=-1&${filter}`) .then(response => { return dispatch(getOffersGridSuccess(response.data)); }); } } 解决方法
我建议你使用redux-thunk包而不是直接在组件中调用api.
接下来,您应该将mapDispatchToProps函数作为第二个参数传递给connect函数,以将action creator函数注入组件: import { getDestinations } from '../actions'; class OffersGridContainer extends React.Component { componentDidMount() { // Tip. const destinationIds = this.props.offers.reduce((acc,[]); // instead `destinationsApi.getDestinations(dispatch,destinationIds)` // call action creator function this.props.getDestinations(destinationIds); } render() { return ( <OffersGridLayout destinations={this.props.destinations} /> ); } } const mapStateToProps = function(store) { return { destinations: store.offersGridState.destinations }; } const mapDispatchToProps = function(dispatch) { return { // this function will be available in component as // `this.props.getDestinations`. getDestinations: function(destinationIds) { dispatch(getDestinations(destinationIds)); } }; } export default connect(mapStateToProps,mapDispatchToProps)(OffersGridContainer); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |