Manchmal wäre es nützlich, einen Speicher pro Instanz in Redux-Anwendungen zu erstellen. Der Schöpfer von Redux selbst erstellt einen Gist, das beschreibt, wie dieses Ziel erreichen: https://gist.github.com/gaearon/eeee2f619620ab7b55673a4ee2bf8400Wie erstellt man einen Store pro Instanz in Redux?
ich diese Frage gestellt schon im Gist aber ich denke, Stackoverflow zu einem besseren Ort für diese Frage sei:
Ich frage mich, wie man dispatch
Aktionen in den komponenteneigenen Spezialspeicher? Gibt es eine Möglichkeit, auf die store
-prop der <Provider />
für jede <SubApp />
(und ihre Kind-Komponenten) zuzugreifen?
Zum Beispiel: Ich habe einige API-Klassen, die dispatch
nach dem Abrufen von Daten von einem Remote-Server aufrufen. Aber da ich den "normalen" Speicher nicht importieren kann, was wäre der beste Weg, mit benutzerdefinierten Speichern umzugehen, um sie für andere Klassen/Dateien/Dienste verfügbar zu machen?
Update 1
Also habe ich es funktioniert, aber ich denke, es ist eine wirklich schmutzige Art und Weise (beachten Sie die UGLY?
Kommentare in den Code):
Anbieter:
einen Speicher erstellen pro durch Erstellen des Speichers im Konstruktor:
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:
Der Anbieter injiziert eine dispatch
Methode für dieses Shop meine OffersGridContainer
die ich Aktionen können nur in den Laden dieser Instanz versenden:
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-Methode:
Verwenden Sie einfach die dispatch
-Methode, die ich als Argument für meine API-Methode übergeben habe:
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;
});
}
Update 2
erhielt nur einen Hinweis auf mapDispatchToProps
in den Kommentaren, so dass meine Container
nun wie folgt aussieht:
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);
Update 3 (die endgültige Antwort)
Jetzt ist alles funktioniert!Hier ist zu Code:
Anbieter:
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>
);
}
}
Container:
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-Methode:
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));
});
}
}
Es gibt einen zweiten Parameter 'connect':' mapDispatchToProps', die Ihnen erlaubt, zu halten die Komponente, die den Versand nicht kennt. –
Danke! Könnten Sie bitte mein Update überprüfen? – Slevin
Nächste Aktualisierung: Ich sollte 'thunk' als Middleware verwenden, damit ich' dispose' nicht als Argument übergeben muss und eine Funktion in meiner 'getDestinations' Methode zurückgeben muss. – Slevin