Using lodash get/set on models within observer() React components #1914
-
I'm looking to create React components that take a path from the root of a store and manage onChange/values based on it, using a composable model type, like so: import { get, set } from 'lodash';
import { types } from 'mobx-state-tree';
export const Pathable = types.model('Pathable', {}).actions((self: object) => ({
getPathValue(keyPath: string): unknown {
return get(self, keyPath);
},
setPathValue(keyPath: string, value: unknown) {
set(self, keyPath, value);
}
}));
export const Store = types.compose(
'Store',
Pathable,
...
);
export const StorePathCheckbox = observer(({ path, ...remaining }: StorePathCheckboxProps) => {
const store = useStore();
const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
store.setPathValue(path, event.target.checked);
};
return <Checkbox {...remaining} onChange={onChange} checked={store.getPathValue(path) as boolean} />;
}); The model verifiably updates when clicking on the checkbox (and there is an UndoManager generating history), but sadly the React component does not rerender. If I explicitly hardwire the get/set of a prop on the model, the component does rerender. I was able to use this approach with lodash's get/set with straight mobx, before moving to MST. Is there something different about MST and |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Hi @kcoop! I think this should work in MST as well, but values returned and used from an export const Pathable = types
.model("Pathable", {})
.views((self: object) => ({
getPathValue(keyPath: string): unknown {
return get(self, keyPath);
}
}))
.actions((self: object) => ({
setPathValue(keyPath: string, value: unknown) {
set(self, keyPath, value);
}
})); |
Beta Was this translation helpful? Give feedback.
-
Ah, there’s the boneheaded mistake. Thank you very much, @EmilTholin! |
Beta Was this translation helpful? Give feedback.
Hi @kcoop!
I think this should work in MST as well, but values returned and used from an
action
will not be observed. You can makegetPathValue
into aview
instead: