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

Question: Async React Reconciler #32046

Open
simonedevit opened this issue Jan 12, 2025 · 3 comments
Open

Question: Async React Reconciler #32046

simonedevit opened this issue Jan 12, 2025 · 3 comments
Labels
Resolution: Needs More Information Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@simonedevit
Copy link

simonedevit commented Jan 12, 2025

Apologies for using the bug template, but I have a question regarding React Reconciler. I understand that this is not intended for questions, and I appreciate your understanding.

I'm building a custom React reconciler by using react-reconciler package. I'm wondering if it is possible having an async reconciler. I need to dynamic import a module in the createInstance method of HostConfig based on the type parameter. A minimal implementation example could be:

// reconciler.ts
async createInstance(type, props, rootContainer, hostContext, internalHandle){
    const Module = await import(`my-module-path/${type}`);
    const instance = new Module();
    return instance;
}

getPublicInstance(instance){
    return instance; // this is a Promise
}

The main issue is that in this way i'm returning a Promise as ref and then i should handle it in this way:

// Component.tsx
  useEffect(() => {
    ref.current.then((instance) => {
      // access here to instance
    })
  }, [ref])

Mine is not a primary renderer so, as workaround, i thought to traversing the Fiber node (generated by React reconciler) to get the all tag names (JSX intrinsic elements) and then dynamic import them before to start the secondary rendering process (createContainer and updateContainer). Unfortunately this not entirely correct because the root Fiber node does not encompass all components of the tree. For example, in the following scenario, only one between the box and the sphere will be included:

condition ? <box /> : <sphere />

Are there other ways to think about this problem?


React (react package) version: 18.3.1
React reconciler (react-reconciler package): 0.29.2

@simonedevit simonedevit added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Jan 12, 2025
@eps1lon
Copy link
Collaborator

eps1lon commented Jan 12, 2025

Can you use React.lazy for that instead?

@simonedevit
Copy link
Author

I'm sorry, i can't get it. Starting from here:

// reconciler.ts
async createInstance(type, props, rootContainer, hostContext, internalHandle){
    const Module = await import(`my-module-path/${type}`);
    const instance = new Module();
    return instance;
}

my returned instance isn't a React component but a pure JavaScript object.

Hemant77777777 added a commit to Hemant77777777/react-meta-fcebook that referenced this issue Jan 13, 2025
@simonedevit
Copy link
Author

simonedevit commented Jan 15, 2025

I can't use React.lazy in my createInstance method because i'm importing JavaScript modules (and not React components). Am i missing something?

I'm wondering if it were possible to throw a promise from the createInstance method of reconciler and then catch it on the React side, leveraging on the power of Suspense. Libraries like react-query and swr already throw a promise, but within their respective hooks that are tied to the component. If it were possible, once the promise is resolved, how could I resume the flow from that point and return the resolved instance?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Needs More Information Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests

2 participants