I want to write opinions after reading some articles about using Backbone Model in ReactJs applications.
Why people still use the old “Backbone Model”?
- In most scenario, the application was backbones-based (from start) and peoples want to migrate only the “View” layer to ReactJs.
- Some peoples choose Backbone Model because they are more familiar with.
Is this “duo” good or bad?
I didn’t see any article telling the advantages of Backbone Model on a ReactJs applications in term of Perf / Testability / Maintainability…
From what I read, peoples usually:
- store Backbone object in components state.
- change the backbone objects… (It means mutate the components state.)
- listen for changes and call
reactComponent.forceUpdate()
sometimes with optimization
It works, ReactJs as a View (greatly) improves the old Backbones-based applications. Make them better, cleaner than before.
BUT.. Backbone Model won’t pull the best out of ReactJs rendering performance.
“Normally you should try to avoid all uses of forceUpdate()…" (Quote from React docs)
In order to get the best out of React. I will resume this official guidelines with my understading and experiences:
- We should implement
shouldComponentUpdate()
on every components (at best!) or on performance-critical components (lists / big components) shouldComponentUpdate(nextProps, nextState)
compares the current state/props with the next state/props and tell React whether to render the components or not.shouldComponentUpdate()
is called frequently, it must to be really fast -> Deep-object comparison is not a choice here (neither Backbone Model) -> it leads to the uses ofPureRenderMixin
withimmutable-js
and cloning objects with ES6Object.assign()
HOWEVER.. I don’t think Backbone Model is bad either.
- Both ReactJs and Backbone Model are desinged as unopinionated library. It is conceptually not wrong to combine them together.
- Evens the rendering is not optimized to the best. The
render()
functions might be called more frequently than it should on the VirtualDOM.. But It is not the end of the world, because therender()
functions are cheap (for the most part). The expensive updates on the real DOM happen only if there are real changes in the VirtualDOM. You might callrender()
a thousand times without triggering any update in the real DOM. - If you cannot use
PureRenderMixin
withimmutable-js
as in the official guidelines:- Implement
toImmutable()
method to return Immutable versions of the data - Use the
ReactImmutableRenderMixin
. It compare state/props withImmutable.is()
instead of the===
strict reference.
- Implement
forceUpdate()
is not recommended to call, but it is not worse than$digest()
and$apply()
of AngularJs (and look how AngularJs works wonderfully)
Conclusion
This duo is not the best, but it is OK.
Nowadays (2015), modern frameworks (AngluarJs, VueJs..) leverage the uses of POJO object as model. In a ReactJs application, my first choice (for now) is Redux.
Model layer, Database and Application State
When we talk about the Model layer in a MV* pattern, peoples tends to match the Model with the database, and see the Model as a 1:1 binding with the database (as if the model is like a database in-memory cache). **It is a mistake**.
For me, the Model stores the Application States.
The Application States is in sync with the UI. So the Model will certainly store a piece of the database which is displaying. The Model also stores application states which are not in the database: eg: start_fetching
(display a progress), fetch_success
(dispose the progress)…