Files
react/packages/react-dom
Andrew Clark 8f96c6b2ac [Bugfix] Prevent infinite update loop caused by a synchronous update in a passive effect (#22277)
* Add test that triggers infinite update loop

In 18, passive effects are flushed synchronously if they are the
result of a synchronous update. We have a guard for infinite update
loops that occur in the layout phase, but it doesn't currently work for
synchronous updates from a passive effect.

The reason this probably hasn't come up yet is because synchronous
updates inside the passive effect phase are relatively rare: you either
have to imperatively dispatch a discrete event, like `el.focus`, or you
have to call `ReactDOM.flushSync`, which triggers a warning. (In
general, updates inside a passive effect are not encouraged.)

I discovered this because `useSyncExternalStore` does sometimes
trigger updates inside the passive effect phase.

This commit adds a failing test to prove the issue exists. I will fix
it in the next commit.

* Fix failing test added in previous commit

The way we detect a "nested update" is if there's synchronous work
remaining at the end of the commit phase.

Currently this check happens before we synchronously flush the passive
effects. I moved it to after the effects are fired, so that it detects
whether synchronous work was scheduled in that phase.
2021-09-09 08:14:30 -07:00
..

react-dom

This package serves as the entry point to the DOM and server renderers for React. It is intended to be paired with the generic React package, which is shipped as react to npm.

Installation

npm install react react-dom

Usage

In the browser

var React = require('react');
var ReactDOM = require('react-dom');

function MyComponent() {
  return <div>Hello World</div>;
}

ReactDOM.render(<MyComponent />, node);

On the server

var React = require('react');
var ReactDOMServer = require('react-dom/server');

function MyComponent() {
  return <div>Hello World</div>;
}

ReactDOMServer.renderToString(<MyComponent />);

API

react-dom

  • findDOMNode
  • render
  • unmountComponentAtNode

react-dom/server

  • renderToString
  • renderToStaticMarkup