gpt4 book ai didi

reactjs - 如何在 Redux 中为每个实例创建一个存储?

转载 作者:行者123 更新时间:2023-12-03 13:51:37 25 4
gpt4 key购买 nike

有时,在 Redux 应用程序中为每个实例创建一个存储会很有用。 Redux 的创建者本身创建了一个 Gist 来描述如何实现这一点:https://gist.github.com/gaearon/eeee2f619620ab7b55673a4ee2bf8400

我已经在 Gist 中问过这个问题,但我认为 StackOverflow 是解决这个问题的更好地方:

我想知道如何dispatch对组件自己的特殊存储的操作?有没有办法访问store <Provider /> 的 -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>
);
}
}

容器:

提供商注入(inject) dispatch 存储到我的方法 OffersGridContainer我可以用它来将操作分派(dispatch)到该实例的存储:

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方法:

只需使用 dispatch -我作为参数传递给 API 方法的方法:

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 函数,以将操作创建器函数注入(inject)组件:

import { getDestinations } from '../actions';

class OffersGridContainer extends React.Component {
componentDidMount() {
// Tip.
const destinationIds = this.props.offers.reduce((acc, offer) => {
return [...acc, ...offer.to.map(d => d.destination)];
}, []);

// 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);

关于reactjs - 如何在 Redux 中为每个实例创建一个存储?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38821882/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com