storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.09k stars 9.25k forks source link

Render React componentes with Concurrent Mode #10543

Closed Thihup closed 2 years ago

Thihup commented 4 years ago

Is your feature request related to a problem? Please describe. I would like to test some componentes to see if is there any problem or any benefits of using Concurrent Mode.

Describe the solution you'd like A way to enable the Concurrent Mode rendering in addition to the current ReactDOM.render call.

Describe alternatives you've considered Not use StoryBook to try Concurrent Mode.

Are you able to assist bring the feature to reality? Yes, I probably would be able to help.

Additional context I think adding the option of testing the components with Concurrent Mode with storybook is a way to make more developers give it a try.

shilman commented 4 years ago

@Thihup I don't think we'll support this in Storybook until concurrent mode is finalized in React itself. If you want to build an experimental package, you could probably clone @storybook/react, add rename it to storybook-react-concurrent, and release it as a standalone package. I'd be happy to help promote your work to the Storybook community. But Storybook core probably won't get it until it's actually ready.

stale[bot] commented 4 years ago

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

stale[bot] commented 4 years ago

Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!

stephtr commented 4 years ago

In case anyone is looking for a quick, DIRTY & temporary fix, I added the following to .storybook/preview.js. However, be warned, that this is probably unstable and definitely unsupported, since it is overriding a part of React. I just used it for a few quick tests.

ReactDOM = require('react-dom');
const nodes = new Map();
ReactDOM.render = (app, rootNode) => {
    let root = nodes.get(rootNode);
    if (!root) {
        root = ReactDOM.unstable_createRoot(rootNode); // depending on your react version this might be `.createRoot`
        nodes.set(rootNode, root);
    }
    root.render(app);
};

ReactDOM.unmountComponentAtNode = (component) => {
    const root = nodes.get(component);
    if (root) {
        root.unmount();
        return true;
    } else {
        console.error("ReactDOM injection: can't unmount the given component");
        return false;
    }
};
snowystinger commented 3 years ago

Should this issue be reopened now that the React 18 alpha is out?

shilman commented 3 years ago

@snowystinger any idea about the release timeline?

snowystinger commented 3 years ago

I only know what the working group has said so far about their release https://reactjs.org/blog/2021/06/08/the-plan-for-react-18.html#projected-react-18-release-timeline Honestly, I'm just starting to wrap my head around this stuff :) and so far, that quick and dirty "fix" hack above is working pretty well. I'll put it through the manual testing paces more soon, I've been trying to work on unit testing as well, it looks like that's in more rough shape at the moment Thanks for reopening and the quick response

wasd171 commented 2 years ago

Given that React 18 beta is out would it be possible to move forward on enabling concurrent mode in Storybook?

snowystinger commented 2 years ago

React RC is out now https://github.com/reactwg/react-18/discussions/9

chantastic commented 2 years ago

React 18 deploys a gradual adoption strategy that could be useful in this transitional period.

In react-dom@rc (18), ReactDOM.render behaves exactly as it did in React 17. This allows the app to be mounted using different root APIs:

if (NEEDS_CONCURRENCY) {
  // new root API
  ReactDOM.createRoot(rootEl).render(<App />);
} else {
  // legacy root API
  ReactDOM.render(rootEl, <App />);
}

They can even be used on the same page simultaneously:

ReactDOM.createRoot(root1).render(<Component1 />);
ReactDOM.render(rootEl2, <Component2 />);

It's also worth noting that only the use of a concurrent feature (startTransition, useDeferredValue, etc.) will change the rendering behavior of a component tree. Save for automatic batching of state hooks, components using public v17 APIs should render identically in React 18

tmeasday commented 2 years ago

@chantastic what is your advice around blocking mode? Are these docs still relevant? https://reactjs.org/docs/concurrent-mode-adoption.html

I would guess we could simply add a framework level feature flag so users can opt-into blocking or concurrent mode, assuming of course they are on an v18 version. Does that sound about right to you?

chantastic commented 2 years ago

@tmeasday yeah, the "modes" concept has been removed in 18.

While not a direct correlation, 'blocking mode' is kinda similar to using the new root API (createRoot) without utilizing any of the new concurrent features.

When using the new root API (createRoot), React 18 only uses the concurrent renderer for component trees that utilize concurrent features. So it' kinda like blocking mode but not explicit. As soon as you take advantage of a concurrent feature, it poisons the downstream component tree.

This discussion might be a valuable in this thread: https://github.com/reactwg/react-18/discussions/70

stale[bot] commented 2 years ago

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

smtrd3 commented 2 years ago

Since react 18 is out now, any update on this?

shilman commented 2 years ago

Ermahgerd!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.5.0-alpha.58 containing PR #17215 that references this issue. Upgrade today to the @next NPM tag to try it out!

npx sb upgrade --prerelease

Closing this issue. Please re-open if you think there's still more to do.

thure commented 2 years ago

Not sure if it’s the same scope as this issue, but the docs addon is still using the legacy root API: renderDocs.tsx is throwing the “ReactDOM.render is no longer supported in React 18” error when rendering an MDX story in the Docs tab (the Canvas tab seems fine).

The legacy API call is here: https://github.com/storybookjs/storybook/blob/0dcd17cbedd91ff3a53abd843ecb2edf684a3637/lib/preview-web/src/renderDocs.tsx#L44

@shilman, should this issue get reopened or is this a separate issue? Happy to write the new issue and maybe take a stab at a PR, whatever would help ✨