Open BenJenkinson opened 4 years ago
Faced a simillar issue, where the methods object was changing on each render because of the initialState
.
function SomeProvider({ children, data }) {
const [state, methods] = useMethods(createMethods, { ...INITIAL_STATE, ...data });
Was able to fix it by memoizing the initialState
as
function SomeProvider({ children, data }) {
const initialState = useMemo(
() => ({ ...INITIAL_STATE, ...data }),
[data]
);
const [state, methods] = useMethods(createMethods, initialState);
Just stumbled upon this. Seems like a basic design flaw, initialState
value shouldn't be tracked.
Also affected.
Looks like they fixed this in the master
:
https://github.com/streamich/react-use/blob/master/src/useMethods.ts
Nope, initialState
is still being tracked for the creation of the methods: https://github.com/streamich/react-use/blob/325f5bd69904346788ea981ec18bfc7397c611df/src/useMethods.ts?rgh-link-date=2022-12-20T13%3A34%3A27Z#L36
It was added in Feb 2020 for some reason: https://github.com/streamich/react-use/commit/b394f3d72356d331dbce48acd3686bbb64d331b5
I opened a PR fixing it: https://github.com/streamich/react-use/pull/2458
What is the current behavior?
The
useMethods
hook wraps the behaviour ofuseReducer
to return a nicely typedmethods
object.https://github.com/streamich/react-use/blob/0fabbcd641e5fc6d16091e7c4c803efe80d7ff56/docs/useMethods.md#L44
However, the
methods
object returned fromuseMethods
is not stable and changes whenever theinitialState
argument changes.This does not match how React treats an
initialState
argument foruseState
anduseReducer
This also does not match how React guarantees the
setState
method fromuseState
and thedispatch
method fromuseReducer
to both be stable and not to change on re-renders or wheninitialState
changes.What is the expected behavior?
I would expect that the
methods
object was guaranteed to be stable and not to change on re-renders or wheninitialState
changes. (Though I would expect it to change if thecreateMethods
argument changed)This would then match the behaviour of the
setState
method fromuseState
and thedispatch
method fromuseReducer
.Investigation
Looking at the source of
useMethods.ts
, I think the current behaviour is unintentional.For example, the dispatch behaviour is already stable, since
createMethods
is re-run for each dispatch call:https://github.com/streamich/react-use/blob/0fabbcd641e5fc6d16091e7c4c803efe80d7ff56/src/useMethods.ts#L19-L24
But the way that the
wrappedMethods
object is created introduces a dependency oninitialState
:https://github.com/streamich/react-use/blob/0fabbcd641e5fc6d16091e7c4c803efe80d7ff56/src/useMethods.ts#L28-L35
I think the bug was introduced accidentally in https://github.com/streamich/react-use/commit/b394f3d72356d331dbce48acd3686bbb64d331b5, since it wasn't present in the original version of the hook.
Version Info
react-use
: 15.2.1, >=13.26.0