-
Notifications
You must be signed in to change notification settings - Fork 530
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: preserve shared state on unmount with a future flag #5123
Conversation
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 87d1851:
|
src/widgets/index/index.ts
Outdated
@@ -450,7 +450,10 @@ const index = (widgetParams: IndexWidgetParams): IndexWidget => { | |||
}; | |||
|
|||
derivedHelper = mainHelper.derive(() => | |||
mergeSearchParameters(...resolveSearchParameters(this)) | |||
mergeSearchParameters( | |||
mainHelper.state, |
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.
this part here is to ensure that "statically set parameters" on mainHelper
persist (parameters on helper
don't, as that actually is the helper of the mainIndex, confusing naming, I know).
Later, we probably should simply get rid of helper
, and replace it with mainHelper
only (which then gets name swapped)
a2e4077
to
1bb6531
Compare
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 8ea7e44:
|
we have ui state and widgets reading this ui state. This means that when you dispose a widget, you don't need to call that function if you start with a clean helper state instead of persisting the state. This needs to be done in a major version, as people _might_ rely on state without ui state (i'm not sure if they do) and that would be removed if they dispose a widget. This allows again for classic react-instantsearch-core style virtual widgets for the modal and dynamic widget use case
de926c3
to
9ff57f1
Compare
Co-authored-by: Haroen Viaene <hello@haroen.me>
safelyRunOnBrowser(() => { | ||
if (options.future?.preserveSharedStateOnUnmount === 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.
why not warn
or warning
? they already take a boolean that can be filled with options.future?.preserveSharedStateOnUnmount !== 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.
A warning might signify to users that not adopting the change will break their implementation, so I preferred a lighter informational message.
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'm mainly thinking of the DEV wrapping for warn. Not sure if info or warn makes much difference though, it's a valid point
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.
Oh right, I didn't think about this and agree it should be scoped to dev mode. I'll add this.
…nt refinements snapshot
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.
Not sure what the right solution is for warn/info but otherwise this lgtm
safelyRunOnBrowser(() => { | ||
if (options.future?.preserveSharedStateOnUnmount === 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.
I'm mainly thinking of the DEV wrapping for warn. Not sure if info or warn makes much difference though, it's a valid point
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.
✔️
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 not use this opportunity to create an tests/common/widgets/index/options.ts
file and test this new behavior in it? No need to migrate the rest of our tests, we can do it separately, but at least we could start "the right way" and test as a user, without manipulating the helper.
Also, we should add a test for the default case (false
, but not passed by the user).
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.
There was a CTS-style test before, but we couldn't get it to pass, not sure if that's stashed anywhere
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.
Yes, I've pushed the CTS here if you want to take a look, basically we saw lifecycle issues with React and Vue in the testing environment for which we could not find solutions for now.
Thanks for the suggestion on the missing test case, I've added it in 58ddb2a.
Co-authored-by: Dhaya <154633+dhayab@users.noreply.github.com>
This PR introduces a functional change in how UI state is handled when widgets are removed from InstantSearch.
Currently, when a widget is removed, its
dispose()
method returns a cleaned state that is used to compute the new shared UI state. This means that if there are multiple widgets targeting the same attribute, when one of them is removed, the widget that is left has its UI state reset as a side-effect.Through the introduction of future flags in InstantSearch, we are able to explicitly switch to a new dispose mode, which doesn't use the cleaned state returned by removed widgets, to allow multiple instances of widgets to keep the refinements active.
It's easy to opt into this new dispose method:
Having this option enabled with a future flag allows us to easily release it without breaking existing implementations, allowing users to adopt it at their own rhythm.
This is made available for InstantSearch.js, React InstantSearch and Vue InstantSearch.
FX-2621
Initial PR description
we have ui state and widgets reading this ui state. This means that when you dispose a widget, you don't need to call that function if you start with a clean helper state instead of persisting the state.This needs to be done in a major version, as people might rely on state without ui state (i'm not sure if they do) and that would be removed if they dispose a widget.
This allows again for classic react-instantsearch-core style virtual widgets for the modal and dynamic widget use case
This could be introduced non-breaking as a different "mode" InstantSearch behaves in, that could be swapped the default value later