Ja, Sie sollten den componentDidMount-Haken definitiv verwenden.
Ein typischer könnte Anwendungsfall sein:
- Komponente erscheint auf dem Bildschirm, zum Beispiel eine Tabelle
- Anfrage an den Server ausgelöst wird, um Daten zu erhalten
- Ein Spinner/loader gezeigt, um die Komponente zu bedecken
- Daten zurück
- Spinner wird entfernt und Daten werden in der Tabelle angezeigt.
Ich weiß, es ist ein bisschen lang, aber ich arbeitete mich auf diese Art von Problem für eine Weile, so dass ich dachte, ich würde das folgende Muster teilen;)
Wenn die Komponente trägt einen dann Daten abrufen Aktion wird ausgelöst. Ein ‚isFetching‘ Wert im Anwendungszustand bestimmt, ob der Spinner dargestellt ist oder nicht (ich glaube, ich ‚advanced-loader‘ oder eine solche Bibliothek verwendet)
export default class MyComponent extends React.Component {
componentDidMount() {
AppDispatcher.dispatch({
type: ActionTypes.FETCH_DATA,
});
}
render() {
let isFetching = this.props.my.application.path.isFetching;
return (
<Loader show={isFetching} message={'loading'}>
<div>
My Component
</div>
</Loader>
);
}
}
Dann im Laden die fetch_data eine Anforderung auslöst:
class AppStore extends ReduceStore {
//......
reduce(state, action) {
let imState = Immutable.fromJS(state);
switch (action.type) {
//......
case ActionTypes.FETCH_DATA:
doGetRequest('/url_to_service');
break;
//......
}
return imState.toJS();
}
}
Der Antrag würde wie folgt aussehen:
function doGetRequest(endpoint, params = {}) {
//request is some kind of AJAX library. In my case 'superagent'
request.get(endpoint)
.set('Accept','application/json')
.query(params)
.end(
(err, res) => {
if (res && res.ok) {
receiveData(endpoint, "SUCCESS", res);
} else {
receiveData(endpoint, "FAIL");
}});
}
Nach Abschluss wäre es dann eine weitere Aktion versenden.
function receiveData(endpoint, state, responseData) {
AppDispatcher.dispatch(
{
type: ActionTypes.SERVER_RESPONSE,
endpoint: endpoint,
state: state,
payload: responseData
}
);
}
zurück in den Laden wird die zweite Aktion gefangen und der isFetching Flag auf falsch gesetzt ist, dann werden die Anwendungsdaten verarbeitet.
reduce(state, action) {
let imState = Immutable.fromJS(state);
switch (action.type) {
//......
case ActionTypes.SERVER_RESPONSE: {
imState = imState.setIn(['my','application','path', 'isFetching'], false)
if (action.state == "SUCCESS") {
//do something with the action.response data (via state update)
}else if (action.state == "FAIL") {
//maybe show an error message (via state update)
}
break;
}
}
return imState.toJS();
}
}
.... so der typische Anwendungsfall verwendet zwei ‚Aktionen‘, die erste Aktion von der Methode componentDidMount ausgelöst wird, und die zweite Aktion wird nach der Anforderung beendet ausgelöst.
Hoffe, dieses Muster hilft :)
ja, es ist der * bevorzugte * Ort, um Aktionen, die Daten für die Komponente initialisieren zu verschicken. –
Hier ist ein wenig mehr zu lesen: https://facebook.github.io/react/docs/react-component.html –
Wie soll ich 'componentDidMount' für die Container-Komponente verwenden, die von redux's connect generiert wird? sollte es in der verpackten Präsentationskomponente gemacht werden und es mit einem Ereignis in den Behälter steigen lassen? oder vielleicht nicht connect und mich selbst in den Laden zu abonnieren? – Pablote