-
Hi, I'm wondering what's the correct way to use React's Considering a simple example such as having a class Store {
threshold = 5
constructor() {
makeAutoObservable(this)
}
} I saw in the docs about Tip: useEffect and observables, which has an example of using // Run the effect when `store.threshold` changed.
useEffect(
() =>
autorun(() => {
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const filtered = list.filter(value => value > store.threshold)
alert(filtered)
}),
[]
) Or you can also combine values from React props/state with MobX observable in // Run the effect when `store.threshold` or `props.list` changed.
useEffect(
() =>
autorun(() => {
const filtered = props.list.filter(value => value > store.threshold)
alert(filtered)
}),
[props.list]
) So I'm wondering what's the correct way to do the same thing, but as a memoized value instead of side effects. // Memoizing value when `store.threshold` changed
const filtered = useMemo(() => {
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
return list.filter(value => value > store.threshold)
}, [store.threshold]) The above code shows eslint warning as follows:
Then I found a way to correctly do it without eslint warning using computed function that behaves like a // Caching (memoizing) value when `store.threshold` changed
const filtered = computed(() => {
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
return list.filter(value => value > store.threshold)
}).get() But when it comes to listening to both // ❌ eslint warning react-hooks/exhaustive-deps
// Memoizing value when `props.list` or `store.threshold` changed
const filtered = useMemo(() => {
return props.list.filter(value => value > store.threshold)
}, [props.list, store.threshold]) // ❌ changes in `store.threshold` will not be reflected
// Memoizing value when `props.list` or `store.threshold` changed
const filtered = useMemo(() => {
return computed(() => props.list.filter(value => value > store.threshold)).get()
}, [props.list]) // ❌ changes in `props.list` will not be reflected
// Memoizing value when `props.list` or `store.threshold` changed
const filtered = computed(() => {
return props.list.filter(value => value > store.threshold)
}).get() Is there a correct way to do this without breaking the eslint rules? Or my ultimate solution is to disable the eslint rule with: // Memoizing value when `props.list` or `store.threshold` changed
const filtered = useMemo(() => {
return props.list.filter(value => value > store.threshold)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.list, store.threshold]) |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
Just found out a solution when tweaking around with the code. Instead of returning the final value through // ❌ changes in `store.threshold` will not be reflected
const filtered = useMemo(() => {
return computed(() => props.list.filter(value => value > store.threshold)).get()
}, [props.list]) Just return the everything as a computed value from // ✅ changes in `props.list` AND `store.threshold` will now be reflected
const filtered = useMemo(() => {
return computed(() => props.list.filter(value => value > store.threshold))
}, [props.list]).get()
|
Beta Was this translation helpful? Give feedback.
-
I'd suggest not to mix props & Mobx at all. Either do your calculations in Mobx and use its |
Beta Was this translation helpful? Give feedback.
Just found out a solution when tweaking around with the code.
Instead of returning the final value through
.get()
insideuseMemo
Just return the everything as a computed value from
useMemo
and use.get()
afterwards:store.threshold
will be tracked throughcomputed
function,props.list
will be tracked …