2017-05-03 6 views
13

Ich bin relativ neu zu reagieren/redux. Da möchte ich eine (vielleicht eine philosophische) Frage stellen.verschicken eine Aktion auf componentDidMount (reagieren/redux)

Ist es in Ordnung, eine Aktion (z. B. zum Auslösen eines API-Anrufs) unter componentDidMount einer Reaktionskomponente zu senden?

Wenn nicht, warum und wo soll ich die Aktion versenden?

Wenn ja, dann keine weiteren Fragen? :)

+5

ja, es ist der * bevorzugte * Ort, um Aktionen, die Daten für die Komponente initialisieren zu verschicken. –

+1

Hier ist ein wenig mehr zu lesen: https://facebook.github.io/react/docs/react-component.html –

+0

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

Antwort

5

Ja, eine Aktion auf componentDidMount() ist in Ordnung, und sogar die empfohlene Sache zu tun, da es nicht die ursprüngliche UI Render verlangsamen wird.

Da die Funktion nach der ersten Wiedergabe der Komponente ausgeführt wird, sollten Sie daran denken, dass Sie möglicherweise zwischen dem Zeitpunkt, an dem die Komponente gerendert wird, und dem Moment, an dem die Daten vom API-Aufruf empfangen werden, liegen.

0

Bei der Verwendung von Routen wäre eine andere empfohlene Möglichkeit, eine Aktion zu versenden, die routes-Methode "onEnter". Dies dient dazu, die Komponente von Aktionen (oder API-Aufrufen) abhängig zu machen.

Ich persönlich denke, beide Methoden (ComponentDidMount vs. OnEnter) sind in Ordnung. Es bleibt dem Programmierer überlassen, welche Lösung für seine Anwendung am besten geeignet ist.

3

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 :)

Verwandte Themen