Skip to content
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

Export context objects that depend on accessing parent context to work when nested #3309

Closed
JacekKiz opened this issue Jul 14, 2022 · 4 comments

Comments

@JacekKiz
Copy link

JacekKiz commented Jul 14, 2022

🙋 Feature Request

Export context objects from @react-aria that depend on accessing parent context to function properly. This would allow for forwarding the context to micro frontend applications where each application is isolated in a separate React tree.

🤔 Expected Behavior

It would be great if FocusContext in @react-aria/focus/src/FocusScope and Context in @react-aria/overlays/src/useModal were exported.

😯 Current Behavior

The context objects are not exported.

💁 Possible Solution

Export the context objects. Something like: #3310

🔦 Context

I work on a project which is using webpack module federation to enable micro frontend architecture. Each micro frontend application is isolated in a separate React tree. The isolation has some benefits and was done for a reason but it also comes with a downside of the context values provided in the parent being inaccessible in a micro frontend app, since it's in a different React tree. When you nest components that use ModalProvider or FocusScope, they require accessing data from parent context to function properly. An example of this would be a Dialog component which contains a micro frontend application inside it and that micro application contains a Picker. If the picker dropdown does not have the connection to Dialog's Focus/Modal context, things don't work as expected (for example, selecting an option within the picker dropdown counts as clicking outside the dialog and the dialog does not get aria-hidden attribute when picker's dropdown is open). In order to get components that use @react-aria's FocusScope and ModalProvider to work with this setup, we would need to use the context and render the provider with the same value in the React root of the micro frontend app.

Is exporting these context objects something you would be open to?

@devongovett
Copy link
Member

We'd prefer not to expose internal contexts. These are implementation details and could change at any time. If we exposed them, this would no longer be possible as they'd become public API.

Without much information, it sounds to me like perhaps your micro frontend architecture is too granular? If you split it such that all components within a modal live within the same react root, you might have an easier time.

In addition, React itself strongly discourages having multiple roots on the page at once. You might want to consider an approach where you expose React components from your split points, and render these within a host component rather than rendering directly into a DOM element as a separate root. This way, everything would be in a single React root, but still split into multiple builds.

@alirezamirian
Copy link
Contributor

alirezamirian commented Jul 18, 2022

We are considering rendering in the same react tree because of these issues and potential concurrency issues in react 18, but at least theoretically it seems to make sense in our setup to isolate our micro frontends as much as possible. In our setup there is a shell application which loads many micro frontends. The most important consideration in rendering those micro frontends in the same react tree is the implicit coupling of the shell application and micro frontends, by having all context providers of the shell application accessible from the micro frontends.
It's true that there is usually some higher level public API on top of each context, and there is no need for directly using context objects. But there are edge cases like this and there are some ways of accommodating for such use cases, without compromising on the public API.

  • Undocumented export with UNSAFE_ prefix. That's what react-router does.
  • Undocumented export, excluded from typings, while one can @ts-expect-error the import and use it on their own risk. Kind of similar to how getCollectionNode is excluded from the public API, but nothing prevents one from accessing it on their own risk.
  • Exporting a utility, specific to this use case. Recoil.js provides useRecoilBridgeAcrossReactRoots, as an example. But I'm guessing you wouldn't be a fan of it :D

Is any of these approaches something you would consider @devongovett ?

@alirezamirian
Copy link
Contributor

In lack of any better solution, we have been using a custom webpack loader to patch @react-aria/overlays and @react-aria/focus to export the context objects. It's obviously a quite fragile patch, causing lots of maintenance overhead so far.
Considering the suggested ways of exporting those context objects won't affect the public API, could you consider exporting them? :)

@snowystinger
Copy link
Member

Closing as we do not want to expose these contexts right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants