Skip to content
This repository has been archived by the owner on Feb 14, 2023. It is now read-only.

Dispatch re-renders components even when state is unchanged. #215

Open
js-jslog opened this issue Oct 11, 2021 · 2 comments
Open

Dispatch re-renders components even when state is unchanged. #215

js-jslog opened this issue Oct 11, 2021 · 2 comments
Labels
bug Something isn't working as expected.

Comments

@js-jslog
Copy link

I am using reactn on 2.2.7 and react on 16.13.1

The react docs on useReducer imply that the state property being dispatched to will not actually be updated if the next value is identical to the previous one: https://reactjs.org/docs/hooks-reference.html#bailing-out-of-a-dispatch (it talks about components not rerendering but presumably the ultimate cause of that is that the state has not been updated)

It looks to me as though this same convention is not being observed in the reactn useDispatch with a global inline property reducer (https://github.com/CharlesStover/reactn#usedispatchfunction-keyof-state) which I would consider an equivalent use case.

// use-dispatch.js - when this dispatch is run...
...
const dispatch = useDispatch((prevStateItem) => prevStateItem, 'stateItem')
dispatch()
...
// component.jsx - ...this component is rerendered
...
const [stateItem] = useGlobal('stateItem')
...

I'm curious to know whether this is known and deliberate, unknown and of interest, or just plain wrongly observed of me.

I'm happy to provide more detailed explanation and examples if it would be helpful.

Thank you for the reactn project. It's been a joy to work with, not least because of the excellent documentation and articles. It's very intuitive and follows from reacts hooks nicely which is obviously a goal of the project. Congratulations.

@quisido
Copy link
Collaborator

quisido commented Oct 11, 2021

Unknown and of interest. Ideally, the component would not re-render in this case.

I wouldn't consider this high enough priority to fix at the moment (a soon React release will add a store observer hook that would offer a better API for listening to state changes), but I'd be open to a PR assuming it is simple enough of a change to ensure no side effects.

Thanks for noticing and reporting this. I'm glad to have it documented.

@quisido quisido added the bug Something isn't working as expected. label Oct 11, 2021
@quisido quisido changed the title Bailing out of dispatch Dispatch re-renders components even when state is unchanged. Oct 11, 2021
js-jslog pushed a commit to js-jslog/harpguru that referenced this issue Oct 12, 2021
After raising this issue
(CharlesStover/reactn#215 (comment))
I'm happy to add this workaround setter which will be used instead of
the existing dispatches in this components hooks.

I will keep the reducers as they are, leaving the logic which determines
whether to return the previous or next property *in* the reducers so
that they would still be applicable to dispatch as would be the
"proper" design.
@js-jslog
Copy link
Author

js-jslog commented Nov 5, 2021

Hi Charles,

Thanks for the roadmap headsup on this. That's interesting to know.

I won't have time to study the code and make a PR, but I can share my workaround for those who need one for performance reasons.

I had the dispatch in question update a different global property which isn't associated with any renders, which means it can afford to be updated on every dispatch with minimal cost. I then setup a useEffect which triggers each time that property is updated, but then only conditionally calls a setter from useGlobal if the object is identical to the previous.

You can set up some boilerplate to make this process reasonably generic, readable and maintainable. You can study the code changes in the PRs mentioned in the previous 2 issue comments here but there are a lot of changes there and a lot of context to dig through so if anyone actually needs this help let me know and I'll put a bit of thought in to breaking it down.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working as expected.
Projects
None yet
Development

No branches or pull requests

2 participants