Reflux V6 Upgrade Gotchas
As part of an upgrade to React 16 in a large app I work on, I also had to upgrade, amongst other libraries, Reflux - the state management library we use - from version 0.2 to 6.4.
I’m not a big fan of Reflux in general, and would generally opt to use Redux in new projects, but we were already tied to it on this project.
As Reflux is less popular than Flux and Redux, there isn’t as much info online. So when you run into problems, you get stuck - or at least I did. In this post I want to share some info about a couple of pitfalls I ran into, in the hope it might help others.
The Store/Component connection
In the previous version of Reflux, we were connecting our Components to the Stores using a decorator:
1
2
@mix.decorate(Reflux.connect(exampleStore))
export default class Example extends React.Component {
One thing I found somewhat confusing at first was that, if you continue to use the above mechanism to connect a Store, it still kind of works in Reflux v6 in the sense that the Store state object will become mixed in with the Component state object.
Ie, if your exampleStore had a state object:
1
2
3
this.state = {
isAnExample: true
}
…then the general idea in Reflux is that the connected Component would also contain the variable, ie: this.state.isAnExample
.
In Reflux 6, with the above code and decorator, you would get this in your Component state: this.state.exampleStore.isAnExample
. So the connection seems to be working, but different. The only issue is that (as far as I could tell), your Component will no longer re-render after the connected Store sends a trigger
event (which basically means the connection is not working and is useless).
I’m not sure whether you are supposed to still be able to use the decorator approach from above in this version of Reflux - in React 16 mixins are deprecated (but not removed). But as far as I can tell, it doesn’t work.
The new method for connecting a Component and Store looks like this:
1
2
3
4
5
6
export default class Example extends Reflux.Component {
constructor(p) {
super (p);
this.stores = [exampleStore];
}
}
So we have to 1) extend Reflux.Component instead of React.Component and 2) list the connected Stores in the Component constructor. Then it goes back to working like the previous version of Reflux did with the state mixing (ie, the exampleStore state variables will be under this.state
, rather than this.state.exampleStore
).
The gotcha
All pretty straightforward. The gotcha for me here is that I was finding certain Components were now connected to Stores, and others were not.
The solution
After trimming down components that did and didn’t work down to their bare bones, I finally figured out my issue:
1
2
3
4
5
6
7
8
9
componentWillMount ()
super.componentWillMount()
... code ...
}
componentWillUnmount ()
super.componentWillUnmount()
... code ...
}
}
Because we’re now extending Reflux.Component, which implements the componentWillMount
and componentWillUnmount
methods, we have to call the super methods. If we don’t, the Store-Component connection will FAIL - silently - and we’ll be left wondering why it’s not working.
The reason for this is actually documented well in the main README of the Reflux docs, although I would have found it a lot quicker if they’d put it in the section about “Hooking stores to components”…
Happy Refluxing!