Fix rerender when location.search changes #178
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
18a3a38 removed the search from the pathname returned from useLocation, but that caused a bug because useState has an optimization that it can avoid a re-render if the state has not changed. Since only the path and not the search was set in the state, React avoids a re-render when only the search changes.
https://reactjs.org/docs/hooks-reference.html#bailing-out-of-a-dispatch
Unfortunately, the test suite didn't pick that up because I suspect there is a difference between the react-testing-renderer and the real browser renderer. I have been trying and logging various re-renders in real React and react-testing-renderer. For whatever reason in the test suite, which uses react-testing-renderer, React does re-render the first time useState is called with the duplicate value, which I suspect is something to do with fibers. This difference caused the test suite to pass even though the real react skips the first update.
Eventually the react-testing-renderer does also stop re-rendering, so it is still possible to include in the test suite. The update
to "/foo?goodbye=world" is the one that fails in the test suite and does not cause a re-render.
To fix, I just include both the path and search in the state so that when the state is updated, it is always re-rendered. There is the check using the ref to prevent re-rendering, so by the time update is called, we know we need a re-render.
All this is orthogonal to the question of exposing the search values directly in the API somewhere. For myself, while it would be nice to have the search params available in the API somewhere, I am just fine parsing them myself. All I need is for the re-render to occur when it changes.