Ich glaube, Sie missverstehen die Datenströme durch Redux. Ich nehme an, wenn Sie die Aktion in ein Versprechen verwandeln wollen, möchten Sie, dass dieses Versprechen aufgelöst wird, wenn der Redux-Status aktualisiert wurde - dies scheint bei Ihrer anderen Frage der Fall zu sein. Dies ist nicht allgemein, wie redux entworfen ist, um zu arbeiten.
Wenn Sie eine Aktion versenden, wird das Geschäft aktualisiert, und dann werden die Requisiten in Ihren Komponenten aktualisiert, die aus dem Geschäft kommen. Alles, was Sie tun müssen, ist diese Requisiten in Ihren Komponenten zu verwenden, und wann immer die Requisiten updaten, wird auch Ihre Komponente.
In Ihrer ersten Frage Code war:
onSubmit(e) {
e.preventDefault();
this.props.nextSentence(); //this is async
this.setState({ //this is not yet updating with the right values then
inputField: this.props.activePupil.name
});
}
Das Problem, das Sie haben, ist, dass activePupil
Teil Ihres redux Speicher ist, aber Sie versuchen, es auch in den Zustand Ihrer Komponente zu speichern. Das ist eine schlechte Idee, weil Sie für Ihren Staat keine einzige Quelle der Wahrheit mehr haben.
Der bessere Ansatz ist es, einfach this.props.activePupil
wo immer es benötigt wird, z.
Jetzt, wenn Sie die Aktion versenden, sobald der Laden aktualisiert wird, wird auch Ihre Komponente aktualisiert. Wenn Sie dann benötigen, können Sie Ihrem Geschäft eine loading
-Eigenschaft hinzufügen, so dass Sie dem Benutzer anzeigen können, dass etwas passiert, und senden Sie diese von Ihrem Thunk, bevor Sie Async-Arbeit ausführen, und.wiederherstellen, wenn UPDATE_ACTIVE
ausgelöst wird.
export const nextPupil =() => {
return (dispatch, getState) => {
dispatch({ type: "PUPIL_UPDATING });
const {activeSentence, sentencesList} = getState();
//... some more code
const nextActive = pupilList[nextIndex];
dispatch({ type: "UPDATE_ACTIVE", payload: nextActive });
}
};
Edit 1
Es ein wenig Gedanken über den richtigen Ansatz, um das Problem unten genommen hat, aber ich denke, dass ich auf eine vernünftige Art und Weise angesiedelt habe, es zu erreichen, während die Datenintegrität zu gewährleisten. Es beinhaltet Formeingabe in Ihrem Geschäft, für die nicht jeder ein Fan ist, aber für mich kein Problem ist.
Wie auch immer ...Wir brauchen ein neues Minderer für Benutzereingabe Handhabung - es wird sehr einfach sein und auf zwei Aktionen reagieren - die „UPDATE_ACTIVE“ Aktion, die Sie bereits haben, und eine „NAME_UPDATED“ Aktion:
const updatedName = (state = '', action) => {
switch (action.type) {
case 'UPDATE_ACTIVE':
return action.payload.name;
case: 'NAME_UPDATED':
return action.payload.updatedName;
default:
return state;
}
};
Dann brauchen wir eine einfache Aktion Schöpfer:
const inputChanged = updatedName => ({
type: 'NAME_UPDATED',
payload: { updatedName }
});
Jetzt in unserer Komponente werden wir die neu geschaffenen Zustand und Aktion Schöpfer verwenden, um unseren Beitrag zu verwalten (connect
sie nur in wie üblich) - viel Code hier fehlt aber sollte es genug sein, um das zu bekommen Idee.
class Whatever extends React.Component {
constructor() {
super();
this.handleChange= this.handleChange.bind(this);
}
handleChange(event) {
this.props.inputChanged(event.target.value);
}
render() {
return (
<input type="text" value={this.props.updatedName} onChange={this.handleChange} />
);
}
}
Ich hoffe, dass es Sinn macht!
Edit 2:
Wenn Sie die Eingabe auf Komponente Zustand speichern möchten, anstatt innerhalb des redux speichern, dann denke ich, dieser Ansatz funktionieren sollte. Es verwendet die componentWillReceiveProps lifecycle hook - um den Komponentenstatus festzulegen, d. H. Den Eingangswert, wenn sich die activePupil
Requisite ändert. Dies wird jedes Mal aufgerufen, wenn die Requisiten aktualisiert werden, kann aber auch aufgerufen werden, wenn es keine Requisitenänderungen gibt. Daher benötigen wir eine Logik, um zu entscheiden, ob die Requisite updatedPupilName
aktualisiert werden soll. Um dies zu erreichen, vergleichen wir unsere aktuellen props.activePupil.name
mit der nextProps.activePupil.name
und aktualisieren nur den Zustand, wenn sie unterschiedlich sind. Wenn Sie eine ID-Eigenschaft auf Ihre Schüler haben, wäre dies wahrscheinlich besser für den Vergleich geeignet.
class Whatever extends React.Component {
constructor(props) {
super(props);
this.state = {
updatedPupilName: props.activePupil.name
};
this.handleChange= this.handleChange.bind(this);
}
componentWillReceiveProps(nextProps) {
if (nextProps.activePupil.name !== this.props.activePupil.name) {
this.setState({
updatedPupilName: nextProps.activePupil.name
});
}
}
handleChange(event) {
this.setState({
updatedPupilName: event.target.value
});
}
render() {
return (
<input type="text" value={this.state.updatedPupilName} onChange={this.handleChange} />
);
}
}
Dies ist eine wirklich gut erklärte Antwort, netter Job :) –
Vielen Dank für die aufwendige Antwort! Mein Problem ist, dass wenn ich 'this.props.activePupil.name' direkt benutze, es für den Benutzer nicht editierbar ist, da es an den Wert des Redux-Shops gebunden ist. Aber ich möchte, dass der Benutzer in der Lage ist, den Wert des Eingabefeldes zu ändern und im Laden zu speichern. Deshalb setze ich einen Zustand des Eingabefeldes dazwischen und gebe den Wert des Geschäfts in das Eingabefeld ein, und bei submit möchte ich das im Speicher speichern. Oder missverstehe ich das ernst? –
Ich werde meine Antwort mit etwas mehr Details bearbeiten. –