-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Infra UI] Selectively persist UI state in the url (via container components) #22980
[Infra UI] Selectively persist UI state in the url (via container components) #22980
Conversation
a909e30
to
272bb73
Compare
💚 Build Succeeded |
💚 Build Succeeded |
export const WithLogFilterUrlState = () => ( | ||
<WithLogFilter> | ||
{({ applyFilterQuery, filterQuery }) => ( | ||
<UrlStateContainer<LogFilterUrlState> |
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.
The mixing TS generics and JSX together reads weird. Can you assign that to a variable then just use the variable? I haven't tried that before so I'm not sure if it will work but it if it does it might make it more readable.
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.
Unfortunately that is not easily possible. The generic type argument has to be passed at instantiation time, which is handled by JSX. If I would convert the UrlStateContainer
component into a class-based component, a no-op inheritance could nail down the type. Alternatively, we could manually type the passed properties sufficiently so the inference figures it out. Typing the return type of mapToUrlState
should do it. Would you think that improves the situation?
<UrlStateContainer
urlState={urlState}
urlStateKey="logPosition"
mapToUrlState={mapToUrlState}
...
/>
const mapToUrlState = (value: any): LogPositionUrlState | undefined => ...
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.
Yeah... that's a lot easier to read.
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.
ok, change coming up...
As per review feedback the container type annotations are not explicitly stated in JSX, but instead inferred through the return type of the `mapToUrlState` function.
💚 Build Succeeded |
@simianhacker ok, I worked around the type arguments in JSX 👆 |
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.
Functionality looks good 👍
@simianhacker are you satisfied with the changes I made to the PR? |
LGTM |
This PR implements syncing of local redux state to the URL via container components. It thereby supersedes #22742, which was the first attempt to achieve that using epics.
UrlStateContainer
The new
UrlStateContainer
component can be used to synchronize a piece of state with a given search parameterurlStateKey
in the URL. It treats the value of that search parameter like a controlled input, which means it persists the state given via theurlState
property rison-encoded to the URL while preserving all other search parameters. Any external changes to the value in the managed search parameter are processed using the function given via themapToUrlState
property the return value of which is passed (along with the previous value) to the function supplied in theonChange
property. In theonChange
function any number of appropriate redux actions (or whatever the state management uses for mutations) can then be dispatched. On initial mounting of the component, theonInitialize
property is called (if supplied) to allow for state initialization at page load or route navigation time.The controlled nature of the search parameter value means that any incoming change that does not lead to a corresponding change in the state will be discarded, because the value is completely derived from the
urlState
.URL State Containers for the store slices
Each of the local
waffle_time
,waffle_filter
,log_position
,log_filter
,log_minimap
andlog_textview
slices have parts of their state persisted to and restored from the URL via containers rendered on their respective pages. Within this PR, the persisted pieces of state are: