Reputation: 1921
In the MobX with React docs, in the Side effects and observables section there is a receipe to respond to changes inside a useEffect
hook.
import React from 'react'
import { autorun } from 'mobx'
function useDocumentTitle(store: TStore) {
React.useEffect(
() =>
autorun(() => {
document.title = `${store.title} - ${store.sectionName}`
}),
[], // note empty dependencies
)
}
The example combines React.useEffect
with mobx.autorun
(but it could be mobx.reaction
), but I can not see the benefit of autorun
in the code. Once we are inside useEffect
we can track our dependencies in the dependency array. The code is more clear, there is no need to dispose()
and useEffect
has a clear dependency array with what is needed.
import React from 'react'
import { autorun } from 'mobx'
function useDocumentTitle(store: TStore) {
React.useEffect(() => document.title = `${store.title} - ${store.sectionName}`
,[store.title, store.sectionName])
}
Is there any reason to follow the example as given?
Here is a Code Sandbox
Upvotes: 8
Views: 9039
Reputation: 8751
autorun
creates an observer, which means it will watch for any changes in store.title
and store.sectionName
, and automatically run whenever they change.
Setting it up in useEffect
ensures that the autorun
observer is only created once, and removed when the component is unmounted. Note that useEffect
doesn't actually run when the store value changes; its effect is that autorun
is (un)registered when the component (un)mounts.
Your second example without autorun
would still run the effect and thus update the title if this component is re-rendered by other means, either because a parent component triggers a re-render, or if this component is wrapped in an observer, as in the Sandbox example:
function Test(props) {
// 2. rerendered by observer when the value changes
useEffect(() => {
// <-- 3. execute effect because (2) rendered with a different dependency
}, [props.store.size]); // <-- 1. observer notes this value is accessed
return ( ... );
}
// <-- 1. observe any store value that is accessed in the Test function
export default observer(Test);
(edited for clarification)
Upvotes: 6