-
-
Notifications
You must be signed in to change notification settings - Fork 19
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
[v3] remove _handleSet from _TemporalState #154
[v3] remove _handleSet from _TemporalState #154
Conversation
Made the discussion here: pmndrs/zustand#2305 |
Ah okay thank you for this! To make sure I understand, is the potential bug of directly modifying setState due to the fact that if multiple nested middlewares do this, setState will just be identical to the last middleware-defined set function instead of applying all nested middleware's set functionality? Or is it that if not all middleware's modify setState, set and setState would differ? I may also still be a little confused... |
Yup, exactly! If the user of the middleware expects that set and setState behave the same, then it's an issue. Looking at this more, I think we'll want to move forward with this change, but it'll have to be for v3 because it's a breaking change. It depends on setState rather than set. |
Ok sounds good! I updated the tests with your suggested fixes, which indeed stopped the tests from failing. If there's anything else you'd like me to do with this PR, just let me know. |
@@ -700,6 +701,7 @@ describe('Middleware options', () => { | |||
}, | |||
1000, | |||
); | |||
store.setState = set; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @pstrassmann, sorry for the delay. Life has been busy and I haven't made time for working on v3 of zundo; however, I'm here now after some good discussions in the zustand repo regarding authoring middleware.
Before merging this in, could you add another test case where store.setState = set
isn't added and we expect .toHaveBeenCalled(0)
? To put it in English, we should have a test case for zundo, there wrapTemporal
fails to be called because we haven't modified the store setter.
src/index.ts
Outdated
currentState, | ||
); | ||
store.temporal.setState({ | ||
...store.temporal.getState(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this line needed here? Shouldn't we only need to be passing pastStates
and futureStates
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I (mistakenly, I think) was under the impression that setState
did not do the kind of auto-merging of state that set
does, which is why I spread the other values here. I will remove this line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha, thanks. I think they both behave the same.
it('should not call function if `store.setState` is not assigned to `set` (wrapTemporal)', () => { | ||
global.console.info = vi.fn(); | ||
const storeWithHandleSet = createVanillaStore({ | ||
wrapTemporal: (config) => { | ||
return (_set, get, store) => { | ||
const set: typeof _set = (partial, replace) => { | ||
console.info('handleSet called'); | ||
_set(partial, replace); | ||
}; | ||
// intentionally commented out | ||
// store.setState = set; | ||
return config(set, get, store); | ||
}; | ||
}, | ||
}); | ||
const { increment } = storeWithHandleSet.getState(); | ||
act(() => { | ||
increment(); | ||
}); | ||
expect(console.info).toHaveBeenCalledTimes(0); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please feel free to suggest a better test description, or if you'd prefer the commented out lines to be removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the great work on this!
This PR removes the
_handleSet
internal property of_TemporalState
in favor of defininghandleSet
withintemporal
(index.ts).This is beneficial from a complexity-reducing standpoint:
_handleSet
no longer needs to be a member of the temporal state, and its functionality is easily discoverable and readable withintemporal
.This change also allows us to remove the type assertion required for accessing private internal properties of
_TemporalState
when usinggetState()
, which returns typeTemporalState
.