2016-06-10 9 views
1

Ich habe Probleme herauszufinden, wo ich einen asynchronen Side-Effects-Handler in meiner React/Redux-Anwendung anlegen kann.Wie behandelt man Nebenwirkungen in react/redux?

Ich benutze React-Router, und alle meine root (oder fast root) Level-Container rufen Versand und Empfang von Updates ohne Probleme. Die Komplikation ist, wo Async-Dienste in diese passen. Hier ein Beispiel:

Routen

<Route path='/' component={App}> 
    <Route path='/home' component={Home} /> 
    <Route path='/locations' component={Locations} /> 
    <Route path='/something-else' component={SomethingElse} /> 
</Route> 

Lassen Sie uns an Orten einen Blick darauf werfen, wo es wahrscheinlich keine Überraschung, die wir brauchen etwas holen:

class Locations extends React.Component<LocationsProps, void> { 
    private _service: StoreService; 

    constructor(props) { 
     super(props); 
     this._service = new StoreService(); 
    } 

    render(): JSX.Element { 
     const { status, stores, selectedStore } = this.props; 
     return (
      <fieldset> 
       <h1>Locations</h1> 
       <StoresComponent 
        status={status} 
        stores={stores} 
        selectedStore={selectedStore} 
        onFetch={this._onFetch.bind(this)} 
        onSelect={this._onStoreSelect.bind(this)} /> 
      </fieldset> 
     ); 
    } 

    private _onFetch(): void { 
     const { dispatch } = this.props; 
     dispatch(fetchStores()); 

     this._service.find() 
      .then(stores => dispatch(loadStores(stores))); 
    } 

    private _onStoreSelect(id: string): void { 
     const { dispatch } = this.props; 
     dispatch(selectStore(id)); 
    } 

    static contextTypes: React.ValidationMap<any> = { 
     status: React.PropTypes.string, 
     stores: React.PropTypes.arrayOf(React.PropTypes.object) 
    }; 
} 

function mapStateToProps(state) { 
    return { 
     status: state.stores.status, 
     stores: state.stores.list, 
     selectedStore: state.stores.selectedStore 
    }; 
} 

export default connect(mapStateToProps)(Locations); 

ich habe Sehr dumm speichert die Komponente, die auf ihren Container angewiesen ist, um die meiste Arbeit zu erledigen. Der Container Orte ist meistens dumm, aber der Teil, der mich stört, ist die _onFetch() Methode, ausgelöst durch einen Klick in der Stores-Komponente.

onFetch() sendet diese Aktion, die den Status auf "Abruf" setzt, aber es interagiert auch mit StoreService, die sich stinkend anfühlt. Wie sollte dies behandelt werden? Damit Locations die Aktion einfach versenden und warten können, bis ihre Requisiten aktualisiert sind?

Was ich in Betracht gezogen habe

Ich habe darüber nachgedacht, alle API-Interaktionen auf der obersten Ebene „app“ Container bewegt, aber das fühlt sich immer noch nicht ganz richtig. Ist es möglich, einen "kopflosen" Listener für den Anwendungsstatus zu abonnieren? dh etwas, das überhaupt nichts machen, und sieht nur wie Anfragen und feuert etwas holen:

this._storeService.find() 
    .then(stores => dispatch(loadStores(stores))); 

Antwort

2

Verwenden Sagas Nebenwirkungen wie async zu tun, setInterval usw.

+0

Es gibt keine Notwendigkeit, sich mit der redux-saga um Nebenwirkungen zu erzielen. Redux-Saga konzentriert sich hauptsächlich auf den Umgang mit asynchronen Action-Machern, ebenso wie auf den alternativen Redux-Thunk. Der beste Weg, um Nebenwirkungen in React/Redux-Apps zu behandeln, könnte darin bestehen, sie in 'componentDidMount' und ** Action-Ersteller ** zu behandeln. –