reflux / refluxjs

A simple library for uni-directional dataflow application architecture with React extensions inspired by Flux
BSD 3-Clause "New" or "Revised" License
5.36k stars 330 forks source link

Reflux stores don't play nice with webpack Hot Module Replacement #385

Open marcelpanse opened 9 years ago

marcelpanse commented 9 years ago

If have simple application using Reflux and everything works properly. I'm using webpack to build and run everything with HMR support. The react components get hot swapped properly and also the Actions and Stores get hot swapped. The only problem is the 'old' Store is still active and still reacting to the Actions. So every compile that changes something in a Store, you end up with another version of the Store.

Is there something that can be done to fix this?

spoike commented 9 years ago

I've peeked into the webpack docs, but still haven't really gotten any insights on how to do it easily with reflux as I'm not using webpack in any project.

Any suggestions on how to proceed with this?

iroy2000 commented 9 years ago

Um... I doubt if it is Reflux issue at all. If you are using webpack-dev-server, will stop the process and start again help at all ? What does the compile message say ?

benglass commented 8 years ago

We have been using reflux on a few projects and just started using webpack hot reloading.

In order to make reflux stores play nicely with hot module reloading the following needs to happen on module.hot

  1. Merge old Store's state into new store's state
  2. Unsubscribe old store from any listeners in order to prevent memory leaks

During a hot swap, you have the opportunity to handle these kinds of cases via code like:

if (module.hot) {
    module.hot.accept(function() {
        // transfer old store state to new store state
    });
    module.hot.dispose(function() {
        // unsubscribe Store from any listeners    
    });
}

I need to do further research into the webpack hot reload api to understand the specific implementation of accept/dispose for these purposes. I'm also not sure if this is possible in a generic implementation with the current reflux API unless there is a specific way that Store state is stored. For example we use Store.data to store the state but this is not a requirement of reflux.

It should also be possible to provide a generic webpack loader which can be applied to stores which automatically adds this hot reloading code to copy old state and remove old subscriptions during a hot reload.

References

yonatanmn commented 8 years ago

Any updates about this topic ? @benglass @spoike

devinivy commented 8 years ago

If some simple boilerplate code or a reflux extension can achieve this, I would personally prefer that over baking it into refluxjs or reflux-core itself.

yonatanmn commented 8 years ago

For my purposes I've added some code to a library I'm building. I'm not sure if it will be relevant to vanilla-reflux, but it's doing this -

accept module at the store itself -> listen to old store from the new modified store. so actions wil call oldStore, new store listens to the triggers, and triggers her own actions.

you can take a look. this functionality is wrapped in a function, and every store file should also call it, maybe babel transformation would have been cleaner.

isaacnass commented 7 years ago

Btw if you just add storeKeys to your components, HMR works perfectly. This also happens to be a really good pattern to follow in my opinion

Spez: You also need to have default values in your state declaration corresponding with the storeKeys that will overwrite them. This is annoying but also not a terrible pattern