With the current implementation, when cursors changes, a new watcher
is created and we subscribe to "update" event. The issue is, if the
value under new path never changes, useBranch will always return the
value from the previous path.
In example below (from documentation), changing alternative prop
will not change colors after first render.
import React, {Component} from 'react';
import {useBranch} from 'baobab-react/hooks';
const List = function(props) {
// Using a function so that your cursors' path can use the component's props etc.
const {colors} = useBranch({
colors: [props.alternative ? 'alternativeColors' : 'colors']
});
function renderItem(color) {
return <li key={color}>{color}</li>;
}
return <ul>{colors.map(renderItem)}</ul>;
}
export default List;
Fix this by re-fetching the current value in the useEffect.
Another issue is that with the current examples, selectors changes
on every render. Passing in an object or function inline will create a
new instance of object on every render, triggering watcher
re-creation.
With the fix above, that leads to an infinite loop:
useEffect sets new value for state
updating state triggers a render
render creates a new selectors triggering useEffect
Fix this by adding a deps argument that should hold an array of
dependencies to trigger re-subscription. The default value is now an
empty array to break the infinite loop and be more
backward-compatible.
Another alternative is to use useMemo to memoize selectors in
examples, but that is overly-verbose and would require a lot of
migration effort for users.
With the current implementation, when
cursors
changes, a new watcher is created and we subscribe to "update" event. The issue is, if the value under new path never changes,useBranch
will always return the value from the previous path.In example below (from documentation), changing
alternative
prop will not changecolors
after first render.Fix this by re-fetching the current value in the
useEffect
.Another issue is that with the current examples,
selectors
changes on every render. Passing in an object or function inline will create a new instance of object on every render, triggering watcher re-creation.With the fix above, that leads to an infinite loop:
useEffect
sets new value forstate
state
triggers a renderselectors
triggeringuseEffect
Fix this by adding a
deps
argument that should hold an array of dependencies to trigger re-subscription. The default value is now an empty array to break the infinite loop and be more backward-compatible.Another alternative is to use
useMemo
to memoize selectors in examples, but that is overly-verbose and would require a lot of migration effort for users.