After switching from Redux to MobX for React I'm starting to extremely like MobX. It's pretty awesome.
MobX has a certain behavior where it won't update component if the provided store observable is not used in render. I think generally that's a pretty great behavior that makes components render only when something actually changed.
But... I do encountered couple of cases where I do not want or need to use MobX observable inside render method and in such cases my this.props.store
with MobX store won't get updated.
And in such cases, as a workaround, I just reference the observable in the render method, but I don't think that's a very clean approach, and I'm wondering if there's a cleaner way to do that?
This component code should explain even more what I'm exactly asking about. It's a component that changes body overflow style based on a MobX observable that I have in my store.
/*------------------------------------*\
Imports
\*------------------------------------*/
import React from 'react';
import connectStore from 'script/connect-store';
import addClass from 'dom-helpers/class/addClass';
import removeClass from 'dom-helpers/class/removeClass';
/*------------------------------------*\
Component
\*------------------------------------*/
class Component extends React.Component {
constructor(props) {
super(props);
this.constructor.displayName = 'BodyClassSync';
}
componentDidMount() {
this.checkAndUpdateMuiClass();
}
componentDidUpdate() {
this.checkAndUpdateMuiClass();
}
checkAndUpdateMuiClass() {
// This place is the only place I need latest MobX store...
if (this.props.store.muiOverlay) {
addClass(window.document.body, 'mod-mui-overlay');
}
else {
removeClass(window.document.body, 'mod-mui-overlay');
}
}
render() {
// This is my workaround so the componentDidUpdate will actually fire
// (with latest and updated store)
// when the 'muiOverlay' observable changes in the MobX store
// Is there any cleaner/better way to do this?
this.props.store.muiOverlay;
// This component doesn't and shouldn't render anything
return null;
}
}
/*------------------------------------*\
Export
\*------------------------------------*/
const ComponentWithStore = connectStore(Component);
export default ComponentWithStore;
(Note: I don't use @decorators, I connect store using ES5 syntax in the connectStore function. And it would be awesome if solution to this would be also in ES5.)