New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No mechanism to keep child React components MobX-agnostic when using custom atoms #3770
Comments
Some thoughts:
If you only want |
Thanks for the reply @mweststrate! I didn't realize the warning can be disabled separately from others, that's great news! The only downside is that disabling it would also disable similar warnings when a It's not obvious to me how to roll a version of
We're aware of where our React hotspots are at the moment and know which trees we would ideally decorate with But disabling this particular warning and applying A bit more context (feel free to ignore): We have a large complex piece of state that is independent of the frontend (it's a core data structure also used by the server and in various other places), which we currently represent in MobX using a single 'dummy' We were drawn to the atom system because this data structure already has its own diffing and change tracking, so it was comparably easy to hook up in order to bridge it to the MobX world. But for the UI code that reads this data structure, there was no forcing function that would have enforced "proper" MobX style, since everything that touched it re-rendered all of the time anyway. For this reason not all components are written in a way that would take full advantage of |
It can be configured per reaction/autorun mobx/packages/mobx/src/api/autorun.ts Line 26 in 1a0dd70
Seems missing in docs, PR welcome :) Technically it's possible to configure it per observer, but currently there is no way to pass the option. |
Workaround mayhaps? :D const atom = createAtom("dummy");
function suppressRequiresObservableWarning() {
atom.reportObserved();
}
const Child = observer((props: { items: Item[] }) => {
suppressRequiresObservableWarning();
return props.items.map(item => (<p>{item.name}</p>));
}); |
When using regular observables, the documentation suggests that
toJS()
at theobserver
level can be used to keep child components MobX-agnostic.However, when using custom atoms
toJS()
has no effect, as tracking is decoupled from the data itself.This leaves us with no way to apply MobX gradually to a complex component tree with minimal pain when using atoms. The suggested way of simply applying
observer
to all child components is very disruptive, since components need to be deeply refactored to dereference data in the proper way, and common components lose their generality as they become coupled to the shape of the data.Here's one of a few illustrative examples we have encountered when following the approach of decorating all child components:
This works fine when the
items
array is non-empty. However, if it's empty, we get:This makes sense, because the
<Child>
component never actually callsreportObserved()
on any atom. However, to solve this, we must either resort to:store.getItems()
logic to the child component, impacting the generality of our components, since<Child>
is often a common component used from many different contexts, oritems
prop togetItems
which<Child>
would call, which then requires the use ofuseCallback()
and can propagate arbitrarily up the hierarchy, causing inconsistency in components and requiring a large engineering effort to implement.Is there any guidance on how to have a top-level component become an
observer
and not requiring large code changes to the complex component tree underneath in the presence of custom atoms? Perhaps a way to makeobserver
consider the component and its descendants as a whole? Are we understanding or using atoms incorrectly?PS. We love MobX, heartfelt thank you to the team for building and maintaining this amazing piece of tech.
The text was updated successfully, but these errors were encountered: