-
-
Notifications
You must be signed in to change notification settings - Fork 39
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
Feat/163 update URL on search page #965
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ycanardeau
force-pushed
the
feat/163-update-url-on-search-page
branch
from
September 14, 2021 14:18
cca883b
to
28358d2
Compare
This was referenced Sep 24, 2021
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Closes #163.
The first attempt
I tried to create two custom hooks:
It was difficult to implement this feature only by using custom hooks.
The second attempt
The most important thing in this implementation was to not update stores directly from the UI. Instead, always set new query params by calling a function. This idea was inspired by React's one-way data flow. See also Sync queryParameters with Redux state and react router for function components.
onClick
,onChange
and etc.).useNavigate
from React Router internally.useEffect
is called.However, there were some drawbacks with this implementation.
The third attempt
I was surprised that riipah already implemented this feature on the song rankings page by using ObservableUrlParamRouter. The third implementation is based on his idea, and basically does two things as I did in the first attempt:
For the first case, it's relatively fast because it only pushes changes to URL (not all child components will be re-rendered). For the second case, it's relatively slow because all child components (except for the ones wrapped with
React.memo
) will be re-rendered. I'd say this is how React Router (React Context) was designed. This implementation uses code from the first and second attempts as well.I couldn't find a way to push changes to URL without re-rendering, but finally I found one. Thanks!
There are still some drawbacks with the current implementation.
How it works
There are three custom hooks:
useStoreWithRouteParams
,useStoreWithUpdateResults
anduseStoreWithPaging
. These hooks are defined as below:The useStoreWithRouteParams hook
The
useStoreWithRouteParams
hook updates a store that implements theIStoreWithRouteParams
interface when a route changes, and vice versa. TheIStoreWithRouteParams
interface is defined as below:The
popState
property is set by theuseStoreWithRouteParams
hook to prevent adding the previous state to history.The
validateRouteParams
function validates route params and should return true if and only if the passed data is valid. Validation happens every timelocation
(not URL) changes, which means, when the page is first loaded, when the back/forward buttons on the browser are clicked, or when the page is navigated to a new location programmatically by using theuseNavigate
hook. For example, the<Link>
component uses theuseNavigate
hook internally.The
routeParams
property gets and sets the state of the store.Source: https://mobx.js.org/reactions.html
The useStoreWithUpdateResults hook
The
useStoreWithUpdateResults
updates search results whenever therouteParams
property changes. TheIStoreWithUpdateResult
interface is defined as below:The
useStoreWithUpdateResults
hook determines if search results should be cleared by comparing the current and previous values. If that's the case, theonClearResults
callback is called.The useStoreWithPaging hook
The
useStoreWithPaging
hook is a helper hook that is composed of theuseStoreWithUpdateResults
anduseStoreWithRouteParams
hooks. TheIStoreWithPaging
interface is defined as below:How to generate schema
We use JSON schema to validate route params. Use
typescript-json-schema project/directory/tsconfig.json TYPE
to generate schema from a TypeScript type. For more information, see https://github.com/YousefED/typescript-json-schema.