Sometimes it would be useful to create one instance for each instance in Redux applications. The creator of Redux himself created a Gist that describes how to do this: https://gist.github.com/gaearon/eeee2f619620ab7b55673a4ee2bf8400
I asked this question already in Gist, but I think StackOverflow will be the best place for this question:
I wonder how to do dispatchactions for your own special repository of components? Is there a way to access store-prop <Provider />for each <SubApp />(and their child components)?
For example: I have some API classes that call dispatchafter retrieving data from a remote server. But since I can't import a βnormalβ store, what would be the best way to handle custom stores to make them available to other classes / files / services?
Update 1
So, I got it working, but I think this is a really dirty way (remember the comments UGLY?inside the code):
Provider:
Create a repository for each instance by creating a repository inside the constructor:
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>
);
}
}
Container:
The provider implements the method dispatchfor this repository to mine OffersGridContainer, which I can use to send actions only to the repository of this instance:
class OffersGridContainer extends React.Component {
componentDidMount() {
const { dispatch } = this.props;
let destinationIds = [];
this.props.offers.forEach((offer) => {
offer.to.forEach((destination) => {
destinationIds.push(destination.destination);
});
});
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 Method:
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 ( )
! :
Provider:
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));
});
}
}