Search code examples
reactjsfluxreactjs-flux

My flux store gets re-instantiated on reload


Okay. I'm kinda new to react and I'm having a #1 mayor issue. Can't really find any solution out there.

I've built an app that renders a list of objects. The list comes from my mock API for now. The list of objects is stored inside a store. The store action to fetch the objects is done by the components.

My issue is when showing these objects. When a user clicks show, it renders a page with details on the object. Store-wise this means firing a getSpecific function that retrieves the object, from the store, based on an ID.

This is all fine, the store still has the objects. Until I reload the page. That is when the store gets wiped, a new instance is created (this is my guess). The store is now empty, and getting that specific object is now impossible (in my current implementation).

So, I read somewhere that this is by design. Is the solutions to:

  1. Save the store in local storage, to keep the data?
  2. Make the API call again and get all the objects once again?

And in case 2, when/where is this supposed to happen?

How should a store make sure it always has the expected data? Any hints?

Some if the implementation:

//List.js

componentDidMount() {
    //The fetch offers function will trigger a change event
    //which will trigger the listener in componentWillMount
    OfferActions.fetchOffers();
}

componentWillMount() {
    //Listen for changes in the store
    offerStore.addChangeListener(this.retriveOffers);
}

retrieveOffers() {
    this.setState({
        offers: offerStore.getAll()
    });
}

.

//OfferActions.js

fetchOffers(){
    let url = 'http://localhost:3001/offers';
    axios.get(url).then(function (data) {
        dispatch({
            actionType: OfferConstants.RECIVE_OFFERS,
            payload: data.data
        });
    });

}

.

//OfferStore.js

var _offers = [];

receiveOffers(payload) {
    _offers = payload || [];
    this.emitChange();
}

handleActions(action) {
    switch (action.actionType) {
        case OfferConstants.RECIVE_OFFERS:
        {
            this.receiveOffers(action.payload);
        }
    }
}

getAll() {
    return _offers;
}

getOffer(requested_id) {

    var result = this.getAll().filter(function (offer) {
        return offer.id == requested_id;
    });

}

.

//Show.js

componentWillMount() {
    this.state = {
        offer: offerStore.getOffer(this.props.params.id)
    };
}

Solution

  • That is correct, redux stores, like any other javascript objects, do not survive a refresh. During a refresh you are resetting the memory of the browser window.

    Both of your approaches would work, however I would suggest the following:

    1. Save to local storage only information that is semi persistent such as authentication token, user first name/last name, ui settings, etc.
    2. During app start (or component load), load any auxiliary information such as sales figures, message feeds, and offers. This information generally changes quickly and it makes little sense to cache it in local storage.

    For 1. you can utilize the redux-persist middleware. It let's you save to and retrieve from your browser's local storage during app start. (This is just one of many ways to accomplish this).

    For 2. your approach makes sense. Load the required data on componentWillMount asynchronously.

    Furthermore, regarding being "up-to-date" with data: this entirely depends on your application needs. A few ideas to help you get started exploring your problem domain:

    • With each request to get offers, also send or save a time stamp. Have the application decide when a time stamp is "too old" and request again.
    • Implement real time communication, for example socket.io which pushes the data to the client instead of the client requesting it.
    • Request the data at an interval suitable to your application. You could pass along the last time you requested the information and the server could decide if there is new data available or return an empty response in which case you display the existing data.