-
-
Notifications
You must be signed in to change notification settings - Fork 635
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
fix(utils): make 'unwrap' update immediate after resolve #2794
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
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. |
Preview in LiveCodesLatest commit: 8ac1645
See documentations for usage instructions. |
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.
Nice catch. Unfortunately the second one is not technically solvable as I understand.
src/vanilla/utils/unwrap.ts
Outdated
const stableFallback = | ||
fallback === defaultFallback | ||
? fallback | ||
: getStableFallback(fallback, anAtom) |
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 doesn't work for certain cases if we want dynamic callbacks.
Let's educate users to define callbacks outside component or use useCallback
.
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.
Alright, I can drop the commit. But could you elaborate just so I understand, what would be the use case? And is it something you would prefer to support over the one in my example above?
Do you mean something like this:
atomWithDefault((get) => get(unwrap(anAsyncAtom, (prev) => prev ?? getSomeDefaultValueThatMayChange())))
Thinking further, this definitely needs to be documented as a breaking change - a Jotai eslint plugin could be useful to disallow inline callbacks here if that's what you mean 🤔
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 a specific use case in mind, but the function can be anything and prev => prev ?? DEFAULT
is only one use case.
It's not a change as I see it. Not only unwrap
, but also useAtomCallback
always expect stable selectors. It's kind of surprising inline callbacks worked in previous versions as it's not intended.
That said, because atomWithDefault((get) => get(unwrap(anAsyncAtom, (prev) => prev ?? DEFAULT)))
worked previously by chance, it's better to document it for explicitly. Would you like to open another PR for doc improvement?
My recommendation is to separate it into two atoms:
const atomA = unwrap(anAsyncAtom, (prev) => prev ?? getSomeDefaultValueThatMayChange());
const atomB = atomWithDefault((get) => get(atomA));
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.
That's fair, thank you. I can make another PR to update the documentation. I'll drop the commit now.
1be57b5
to
789d671
Compare
8646d73
to
ed87699
Compare
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 code diff looks good to me.
Please check CI errors and update the PR description.
2c1bc0a
to
9f0fcfa
Compare
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.
LGTM. Thanks for your contribution.
Will merge it next week.
9f0fcfa
to
ca6bcae
Compare
ca6bcae
to
2fbac34
Compare
Co-authored-by: Daishi Kato <dai-shi@users.noreply.github.com>
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [jotai](https://github.com/pmndrs/jotai) | dependencies | minor | [`2.9.3` -> `2.11.0`](https://renovatebot.com/diffs/npm/jotai/2.9.3/2.11.0) | --- ### Release Notes <details> <summary>pmndrs/jotai (jotai)</summary> ### [`v2.11.0`](https://github.com/pmndrs/jotai/releases/tag/v2.11.0) [Compare Source](pmndrs/jotai@v2.10.4...v2.11.0) There are no public API changes, but some internal behaviors have been improved. Now, atom updates are batched in a single write, which might provide a performance benefit in certain edge cases. This feature has been requested actually for a long time, and it's finally implemented. See also [#​2782](pmndrs/jotai#2782). #### What's Changed - refactor(store): rename pending to batch by [@​dai-shi](https://github.com/dai-shi) in pmndrs/jotai#2868 - lazy recomputeDependents by [@​dmaskasky](https://github.com/dmaskasky) in pmndrs/jotai#2827 - fix(store): robust flush batch by [@​dmaskasky](https://github.com/dmaskasky) in pmndrs/jotai#2871 - fix(store): refactor batch priority by [@​dmaskasky](https://github.com/dmaskasky) in pmndrs/jotai#2875 - feat: dev store with unstable_derive by [@​dai-shi](https://github.com/dai-shi) in pmndrs/jotai#2852 #### New Contributors - [@​rainagalbiati-turngate](https://github.com/rainagalbiati-turngate) made their first contribution in pmndrs/jotai#2882 - [@​leweyse](https://github.com/leweyse) made their first contribution in pmndrs/jotai#2883 **Full Changelog**: pmndrs/jotai@v2.10.4...v2.11.0 ### [`v2.10.4`](https://github.com/pmndrs/jotai/releases/tag/v2.10.4) [Compare Source](pmndrs/jotai@v2.10.3...v2.10.4) A minor improvement for some edge cases. (For more information, see [#​2789](pmndrs/jotai#2789).) #### What's Changed - fix(store): do not recompute unmounted atoms eagerly by [@​dai-shi](https://github.com/dai-shi) in pmndrs/jotai#2849 #### New Contributors - [@​rmillio](https://github.com/rmillio) made their first contribution in pmndrs/jotai#2832 - [@​sukvvon](https://github.com/sukvvon) made their first contribution in pmndrs/jotai#2851 **Full Changelog**: pmndrs/jotai@v2.10.3...v2.10.4 ### [`v2.10.3`](https://github.com/pmndrs/jotai/releases/tag/v2.10.3) [Compare Source](pmndrs/jotai@v2.10.2...v2.10.3) This fixes various edge cases. Huge thanks to [@​dmaskasky](https://github.com/dmaskasky) ! 🎉 #### What's Changed - fix: flushPending in async write by [@​dai-shi](https://github.com/dai-shi) in pmndrs/jotai#2804 - fix: flush pending finally everywhere by [@​dmaskasky](https://github.com/dmaskasky) in pmndrs/jotai#2818 - fix: rethrow falsy errors thrown in flushPending by [@​dmaskasky](https://github.com/dmaskasky) in pmndrs/jotai#2820 - fix: setAtom uses stale pending on atom unmount by [@​dmaskasky](https://github.com/dmaskasky) in pmndrs/jotai#2811 - fix: onMount setSelf does not notify listeners by [@​dmaskasky](https://github.com/dmaskasky) in pmndrs/jotai#2815 - refactor(core): Use iterative approach in recompute dependents by [@​dmaskasky](https://github.com/dmaskasky) in pmndrs/jotai#2821 - refactor(store): prefer epoch number comparisons to indicate value change by [@​dmaskasky](https://github.com/dmaskasky) in pmndrs/jotai#2828 **Full Changelog**: pmndrs/jotai@v2.10.2...v2.10.3 ### [`v2.10.2`](https://github.com/pmndrs/jotai/releases/tag/v2.10.2) [Compare Source](pmndrs/jotai@v2.10.1...v2.10.2) Fixed some jotai/utils for a regression in v2.10.0. #### What's Changed - fix(unstable_derive): trap atom methods by [@​dai-shi](https://github.com/dai-shi) in pmndrs/jotai#2741 - Throw error on `useAtom(undefined)` or `useAtom(null)` by [@​kevinschaich](https://github.com/kevinschaich) in pmndrs/jotai#2778 - fix(utils): make 'loadable' update immediate after resolve by [@​e7h4n](https://github.com/e7h4n) in pmndrs/jotai#2790 - fix(utils): make 'unwrap' update immediate after resolve by [@​organize](https://github.com/organize) in pmndrs/jotai#2794 #### New Contributors - [@​niklasbec](https://github.com/niklasbec) made their first contribution in pmndrs/jotai#2773 - [@​romain-trotard](https://github.com/romain-trotard) made their first contribution in pmndrs/jotai#2781 - [@​kretajak](https://github.com/kretajak) made their first contribution in pmndrs/jotai#2786 - [@​Brokyeom](https://github.com/Brokyeom) made their first contribution in pmndrs/jotai#2798 - [@​ryoku4](https://github.com/ryoku4) made their first contribution in pmndrs/jotai#2802 - [@​yairEO](https://github.com/yairEO) made their first contribution in pmndrs/jotai#2805 - [@​kevinschaich](https://github.com/kevinschaich) made their first contribution in pmndrs/jotai#2778 - [@​e7h4n](https://github.com/e7h4n) made their first contribution in pmndrs/jotai#2790 - [@​organize](https://github.com/organize) made their first contribution in pmndrs/jotai#2794 **Full Changelog**: pmndrs/jotai@v2.10.1...v2.10.2 ### [`v2.10.1`](https://github.com/pmndrs/jotai/releases/tag/v2.10.1) [Compare Source](pmndrs/jotai@v2.10.0...v2.10.1) This fixes a bug in an extreme edge case. If you find this change breaks something, please report to us. #### What's Changed - fix(core): recompute dependents in edge cases by [@​dai-shi](https://github.com/dai-shi) in pmndrs/jotai#2742 #### New Contributors - [@​vangie](https://github.com/vangie) made their first contribution in pmndrs/jotai#2753 - [@​ts1994tw](https://github.com/ts1994tw) made their first contribution in pmndrs/jotai#2759 - [@​KagamiChan](https://github.com/KagamiChan) made their first contribution in pmndrs/jotai#2761 - [@​nguyenbry](https://github.com/nguyenbry) made their first contribution in pmndrs/jotai#2762 - [@​jaycho46](https://github.com/jaycho46) made their first contribution in pmndrs/jotai#2766 - [@​midzdotdev](https://github.com/midzdotdev) made their first contribution in pmndrs/jotai#2767 **Full Changelog**: pmndrs/jotai@v2.10.0...v2.10.1 ### [`v2.10.0`](https://github.com/pmndrs/jotai/releases/tag/v2.10.0) [Compare Source](pmndrs/jotai@v2.9.3...v2.10.0) It comes with another significant internal change to address some edge cases. Since v2.9.0, we've been working on some internal refactors to support more edge cases and clean up the code. Users are encouraged to update to the new versions eventually, but if you're satisfied with the current situation and prefer to avoid temporary instability, you can stick with v2.8.4 for now. #### What's Changed - breaking(core): avoid continuable promise in store api by [@​dai-shi](https://github.com/dai-shi) in pmndrs/jotai#2695 #### New Contributors - [@​sphinxrave](https://github.com/sphinxrave) made their first contribution in pmndrs/jotai#2653 - [@​mxthxngx](https://github.com/mxthxngx) made their first contribution in pmndrs/jotai#2712 - [@​hoangvu12](https://github.com/hoangvu12) made their first contribution in pmndrs/jotai#2716 - [@​YuHyeonWook](https://github.com/YuHyeonWook) made their first contribution in pmndrs/jotai#2734 **Full Changelog**: pmndrs/jotai@v2.9.3...v2.10.0 </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS41Ny40IiwidXBkYXRlZEluVmVyIjoiMzkuODIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: https://git.tristess.app/alexandresoro/ouca/pulls/380 Reviewed-by: Alexandre Soro <code@soro.dev> Co-authored-by: renovate <renovate@git.tristess.app> Co-committed-by: renovate <renovate@git.tristess.app>
Related Bug Reports or Discussions
Identical to #2790, but for
unwrap
This regression is from the change here: #2695
Summary
When upgrading from 2.8.4 to 2.10.1,
unwrap
hangs in certain cases. I narrowed it down to atoms such as this one:atomWithDefault((get) => get(unwrap(anAsyncAtom)))
Applying #2790 to
unwrap
fixes things.Note that the recommended pattern for such atoms is to use two atoms:
In this case, inlining
atomA
intoatomWithDefault
only works ifunwrap
's default fallback is used, meaning the following code will hang:const atomB = atomWithDefault((get) => get(unwrap(anAsyncAtom, (prev) => prev ?? 'MAGIC_DEFAULT')));
Check List
pnpm run prettier
for formatting code and docs