SSR compatibility patch for useId(...)#959
Conversation
…on instead of random number to preserve client/server match
| { | ||
| "name": "@react-aria/utils", | ||
| "version": "3.1.0", | ||
| "version": "3.1.1", |
There was a problem hiding this comment.
when we publish with lerna, this'll get updated, so no need to do it in PR
There was a problem hiding this comment.
perfect. I couldn't tell it this project auto-versioned or not.
| const PACKAGE_JSON = 'package.json'; | ||
|
|
||
| // returns path to closest package.json file while traversing up from given filepath | ||
| // this is compatible with a yarn/lerna workspaces environment |
There was a problem hiding this comment.
Did you try this? https://github.com/sindresorhus/read-pkg-up
There was a problem hiding this comment.
No I haven't, but that looks exactly like what I wanted. I'll add a commit to use that instead.
Does this project have a preference of it's-fine-to-include-a-dependency vs. this-is-simple-no-need-for-another-dependency?
|
|
||
| let id = 0; | ||
| // don't want to conflict with ids from v2, this will guarantee something unique | ||
| // don't want to conflict with ids from other instances of this module, this will *mostly* guarantee something unique |
There was a problem hiding this comment.
so this will avoid collisions with different versions of the same module, but doesn't do anything for the case where two copies of the same version are loaded, which is something we might see in a micro frontend architecture
we'll need to still do something to protect against that
Unfortunately, that seems to indicate the need for a global :(
If you have any ideas, feel free to post them in thread here, I'll also confer with my team and see if they have more ideas
There was a problem hiding this comment.
so this will avoid collisions with different versions of the same module, but doesn't do anything for the case where two copies of the same version are loaded, which is something we might see in a micro frontend architecture
exactly. I ran into this just the other day when I was de-duping a dependency tree in one of our apps. This scenario can definitely happen, but it can also be solved (in npm with some fun dependency updating and/or npm dedupe usage, or in yarn with atlassian's yarn-deduplicate tool), but that is just a workaround for this issue that will certainly arise.
Unfortunately, that seems to indicate the need for a global :(
I agree. A WeakMap could be used to hold onto the versions for the different instances in play.
The question that remains is what should the expected behavior be? It could:
- throw an error when a duplicate instance of same version is in use (force devs to dedupe)
- print a warning when a duplicate instance of same version is in use (nicer to dev workflow)
- allow multiple instances of the same version. both instances share the same counter
- allow multiple instances of the same version, duplicate instances append -{n} to the id before the counter.
A lot of this seems like overkill. the simplest seems to be:
- allow multiple instances of the same version. both instances share the same counter
and at that point, probably don't even need to add the version number in there. just a global counter for the id variable that all module instances can share from. (this comment has me thinking this could all be that much simpler case: facebook/react#5867 (comment) .)
|
Thanks for looking into this and sharing how much is fixed with just this little change! |
This reverts commit be92d95.
|
Nice! I see two potential issues here, in addition to the multiple copies issue discussed above:
One possibility is a context to store the value to increment. Applications would be required to wrap their app in a provider component, which would set the value to zero, and be incremented by each call to All that sounds pretty complicated though, and would expose a lot of implementation details to application authors, increasing the potential for bugs. An alternative we might be able to get away with would be to just return In the future, we should be able to use React's What do you think of these options? |
This sounds like the best option to me, and that would allow the |
|
Added the change to the |
|
removed the local babel plugin from this implementation, so with the babel plugin was getting in the way of the |
|
Lots of failing tests in the circle ci run. This module runs deep. |
|
I have a feeling you're going to run into a problem pretty quickly right here https://github.com/adobe/react-spectrum/blob/main/packages/%40react-aria/utils/src/useId.ts#L61 |
|
When I use 💻 Code Sample |
|
@benjroy so, I did a bit of investigation here, and basically concluded that the returning null approach wasn't going to work, or at least not easily. As evidenced by the failing tests, too many things depend on I've gone ahead and implemented the other suggestion above in #992. Basically you'll need to wrap your application in an Feel free to provide your feedback on the PR! Thanks again for getting this started. 😄 |
I'm evaluating
@react-ariafor use in NerdWallet's frontend stack.First, I'd like to complement you all. This project is incredible. The semantics of the hooks have me hooked. The documentation for this project is incredibly valuable: https://react-spectrum.adobe.com/react-aria
We need SSR support in order to use this package. When I came across the following comment, it made me want to test the waters of how responsive this project is to external contributions. If y'all are receptive, we'd love to contribute more patches for SSR compatibility.
#842 (comment)
This PR patches the
useId(id)hook to be SSR compatible. It removes the use ofMath.random()to seed the ids it generates in order to keep the generated id consistent between server-response and client hydration. It replaces the random number with the current package version of @react-aria/utils, in order to keep the spirit from the comment in that file of having something visible for devs to see that multiple instances of the module are in use.I hooked up a local babel plugin to inject the package version during babel transpilation
This patch solves ~60% of the ssr tests that are currently failing.
yarn test:ssrbefore:yarn test:ssrafter:P.S. for anyone else reading, the discussion concerning
isomorphic idsin this react issue helped with context of this kind of issue. facebook/react#5867✅ Pull Request Checklist:
📝 Test Instructions:
yarn test:ssrRelated Issues:
#760
#835
#899
#842