1

I have a simple navigation bar use case where I have

Components

  • NavBar.jsx
  • NavBarItem.jsx

Stores

  • NavStore.js

Using Dependencies

  • React
  • Reflux

I'd render the navbar like

<NavBar active={itemName} itemList={itemList} />

The question is my initial state is {}, so is my NavStore, since there's no external data involved, how should I initialize the NavStore.js with itemList information?

I tried to add a helper method on Store like initializeData(data), and call it in NavBar Component's render or getInitialState(), it somehow is always getting called after a this.setState() on Component and reinitialized store with initial values. Not sure why getInitialState() always get called on this.setState().

I am also using Reflux as the action dispatcher but I am seeing the getInitialState() called on every action. It seems a bit odd. Does Reflux trigger a recreation of component by default?

ttback
  • 2,051
  • 5
  • 27
  • 40
  • getInitialState is not called on each render call, or setState, it is called only once when the component is mounted. Are you sure you are not recreating your component each time? – Jeremy D Mar 19 '15 at 02:25
  • @JeremyD I am seeing the getInititalState called many times as I send out an update event, even though there's no explicit calls made to recreate the element every time. I wonder if Reflux has something to do with that. – ttback Mar 19 '15 at 16:02

1 Answers1

1

Write an initialize function that initiates an action called INITIALIZE_APP and have the necessary stores perform initialization on receiving this action. Wait for all the stores to finish the initialization before rendering the root react component.

//initialize.js
var initialize = function() {
    var dispatchToken = AppDispatcher.register(payload => {
        var action = payload.action;

        if (action.type !== AppConstants.ActionTypes.INITIALIZE_APP) {
            return;
        }
        //  wait    for all the stores  to  initialize  before rendering
        var tokens = [
            CustomerStore,
            NavigationStore,
        ].map(store => store.dispatchToken);

        AppDispatcher.waitFor(tokens);
        AppDispatcher.unregister(dispatchToken);
    });

    InitializeAppActions.initialize(); //   Creates INITIAL_LOAD    action
};

module.exports = initialize;

Have an action defined for INITALIZE_APP

// InitializeAppActions.js
var InitializeAppActions = {
  initialize() {
    AppDispatcher.handleViewAction({
      type: ActionTypes.INITIALIZE_APP,
    });
    return true;
  },

};

module.exports = InitializeAppActions;

The store listens to the INITIALIZE_APP action

//CustomerStore.js
CustomerStore.dispatchToken = AppDispatcher.register(function(payload)   {
  var action = payload.action;
  switch (action.type) {

    //Called when the app is started or reloaded
    case ActionTypes.INITIALIZE_APP:
        initializeCustomerData();
        break;
}

Call the initialize function before the executing the root react component.

//app.js
var initialize = require("./initialize.js");


//initialize the stores before rendering
initialize();

Router
.create({
  routes: AppRoutes,
})
.run(function(Handler) {
  React.render( <Handler/>, document.getElementById("react-app"));
});
Sid
  • 81
  • 1
  • 4
  • Hmm that code looks familiar ;) The OP is using Reflux, so there is no dispatcher. BTW, depending on your module loading system and how you're structuring the application bootstrap, you may or may not need to do the whole register/waitFor/unregister thing. A simpler example is here on slide 73: https://speakerdeck.com/fisherwebdev/flux-applicative – fisherwebdev Mar 19 '15 at 17:15
  • Yup, it was from an earlier comment of yours. Couldn't find the link to the exact question. Sorry. The question was modified to specify he's using reflux. – Sid Mar 20 '15 at 01:24