The Flux model mandates that any changes in state initiated at the views, fire actions that work through the dispatcher and propagate down a store back to listening views.
This is all nice and dandy. But what if I need to perform some DOM operation after a specific change in state? In real world apps, we sometimes have to use that, you know, relic called jQuery plugins (remember those?)
For example, I need to initialize a jQuery video player, à la $('#videoContainer').initPlayer(streamURL)
, after an Ajax request to retrieve streamURL
. Please dedicate a moment to figure out how you would do that with Flux/React, before reading on).
On the view part, I might use componentWillReceiveProps
:
var jsVideoPlayer = React.createClass({
componentWillReceiveProps: function(nextProps) {
$(this.refs.videoContainer.getDOMNode()).initPlayer(nextProps.streamURL);
},
render: function() {
return (
<div ref="videoContainer">
</div>
);
}
});
But here, the player would get initialized each time the state updates. That would surely break our video player. So let's check if the URL has changed before we actually do anything:
componentWillReceiveProps: function(nextProps) {
if (nextProps.streamURL && nextProps.streamURL !== this.streamURL) {
this.streamURL = nextProps.streamURL;
$(this.refs.videoContainer.getDOMNode()).initPlayer(nextProps.streamURL);
}
},
Easy, right? But what about the bigger picture? What if we scale that up - and wide - as we add more functionality and UI elements, that could lead to more custom validation code in the views on what's coming down from the store. Even in a perfect app, where every store has it's own domain and everything is laid out spotlessly in design patterns on a level worthy of a dedicated religious following, we would still have to use more and more logic in the views as the app would scale.
In our team, I argued this logic should really go into a ControllerView, which fits the Flux model - but everyone else argued this is something the framework should take care of. We are new to Flux/React, and couldn't come up with a better idea on how to make the framework do that for us.