kjda / ReactFlux

A library implementing React-Flux data flow design pattern + Code Generation
MIT License
66 stars 12 forks source link

Triggering an action when another store changes state #19

Closed aforty closed 9 years ago

aforty commented 9 years ago

Hi, I've been using this library for the better part of a month now and I've found it very useful. However, I'm wondering if this scenario is supported and, if so, how to best implement it.

Essentially, I have a SessionStore and when the user logs in, I want another action to kick off and retrieve the users order history, favorites, etc. What's the best approach to do this?

kjda commented 9 years ago
  1. you can create a "coordinator"-component (or even on login-page-component itself) that listens to SessionStore and kick off dependent actions when status changes to "logged in"
  2. The better option: let's say after user logs in, you redirect him to his profile page, or you display a subview that needs some data.. there you should check if you already fetched required data for that view.. you could do it inside componentDidMount by having a flag "didLoad" in your stores(history, favorites, etc) state
//Profile view
getStateFromStores () {
     return {
        didLoad: store.get('didLoad'),
        data: store.get('someOtherData')
      };
   },

  componentDidMount(){
       if( !this.state.didLoad ){
           actoins.fetch();
       }
   }
}

//you need to toggle didLoad on FETCH_SUCCESS in your store
aforty commented 9 years ago

Thanks for the quick response! Ok so one of the component(s) is the correct place to trigger additional actions is what I'm gathering.

I never redirect to another page on login, just update the state and the navigation re-renders as a result. Where in the component (page level) would I then detect the change? componentDidMount() won't retrigger at that point, so is it ok to just trigger new actions in render() or should I attach a listener that waits for a very specific action to complete?

Side question: Facebook's Flux blog extensively talks about the dispatcher being capable of waitFor() for scenarios where one store may want to wait for another store to finish processing before continuing. I haven't run into this scenario yet but I imagine I will at some point. How would one handle this in react-flux?

Source: http://facebook.github.io/react/blog/2014/07/30/flux-actions-and-the-dispatcher.html Example: https://github.com/facebook/flux/blob/master/examples/flux-chat/js/stores/MessageStore.js

kjda commented 9 years ago

"redirecting" was a bad choice! I meant when a new page component enters the scene.. if you have a single component, you can detect state changes using React lifecycle callbacks, example:

componentDidUpdate(prevProps, prevState) { 
    if(  this.state.isAuth && !this.state.didLoad && !this.state.isLoading ) {  
        actions.fetch() 
    } 
}

You should NEVER trigger any state changes from within render()!!!

yes, waitFor is supported! have a look at the example here https://github.com/kjda/ReactFlux/blob/master/examples/example1/flux/stores/user.js

aforty commented 9 years ago

Excellent, on both fronts! Thanks so much for your help!

kjda commented 9 years ago

you are welcome!