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

Remove <React.unstable_ConcurrentMode /> element type #15532

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 5 additions & 9 deletions fixtures/unstable-async/time-slicing/src/index.js
@@ -1,6 +1,6 @@
import React, {PureComponent} from 'react';
import {flushSync, render} from 'react-dom';
import {unstable_scheduleCallback} from 'scheduler';
import {flushSync, unstable_createRoot} from 'react-dom';
import Scheduler from 'scheduler';
import _ from 'lodash';
import Charts from './Charts';
import Clock from './Clock';
Expand Down Expand Up @@ -67,7 +67,7 @@ class App extends PureComponent {
}
this._ignoreClick = true;

unstable_scheduleCallback(() => {
Scheduler.unstable_next(() => {
this.setState({showDemo: true}, () => {
this._ignoreClick = false;
});
Expand Down Expand Up @@ -146,9 +146,5 @@ class App extends PureComponent {
}

const container = document.getElementById('root');
render(
<React.unstable_ConcurrentMode>
<App />
</React.unstable_ConcurrentMode>,
container
);
const root = ReactDOM.unstable_createRoot(container);
root.render(<App />, container);
111 changes: 11 additions & 100 deletions packages/react-dom/src/__tests__/ReactDOMFiberAsync-test.internal.js
Expand Up @@ -16,8 +16,6 @@ let ReactFeatureFlags = require('shared/ReactFeatureFlags');
let ReactDOM;
let Scheduler;

const ConcurrentMode = React.unstable_ConcurrentMode;

const setUntrackedInputValue = Object.getOwnPropertyDescriptor(
HTMLInputElement.prototype,
'value',
Expand Down Expand Up @@ -86,12 +84,9 @@ describe('ReactDOMFiberAsync', () => {
);
}
}
ReactDOM.render(
<ConcurrentMode>
<Counter />
</ConcurrentMode>,
container,
);
const root = ReactDOM.unstable_createRoot(container);
root.render(<Counter />);
Scheduler.flushAll();
expect(asyncValueRef.current.textContent).toBe('');
expect(syncValueRef.current.textContent).toBe('');

Expand All @@ -108,34 +103,7 @@ describe('ReactDOMFiberAsync', () => {
expect(syncValueRef.current.textContent).toBe('hello');
});

describe('with feature flag disabled', () => {
beforeEach(() => {
jest.resetModules();
ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactDOM = require('react-dom');
Scheduler = require('scheduler');
});

it('renders synchronously', () => {
ReactDOM.render(
<ConcurrentMode>
<div>Hi</div>
</ConcurrentMode>,
container,
);
expect(container.textContent).toEqual('Hi');

ReactDOM.render(
<ConcurrentMode>
<div>Bye</div>
</ConcurrentMode>,
container,
);
expect(container.textContent).toEqual('Bye');
});
});

describe('with feature flag enabled', () => {
describe('concurrent mode', () => {
beforeEach(() => {
jest.resetModules();
ReactFeatureFlags = require('shared/ReactFeatureFlags');
Expand All @@ -144,7 +112,7 @@ describe('ReactDOMFiberAsync', () => {
Scheduler = require('scheduler');
});

it('createRoot makes the entire tree async', () => {
it('top-level updates are concurrent', () => {
const root = ReactDOM.unstable_createRoot(container);
root.render(<div>Hi</div>);
expect(container.textContent).toEqual('');
Expand All @@ -157,7 +125,7 @@ describe('ReactDOMFiberAsync', () => {
expect(container.textContent).toEqual('Bye');
});

it('updates inside an async tree are async by default', () => {
it('deep updates (setState) are oncurrent', () => {
let instance;
class Component extends React.Component {
state = {step: 0};
Expand All @@ -179,56 +147,6 @@ describe('ReactDOMFiberAsync', () => {
expect(container.textContent).toEqual('1');
});

it('ConcurrentMode creates an async subtree', () => {
let instance;
class Component extends React.Component {
state = {step: 0};
render() {
instance = this;
return <div>{this.state.step}</div>;
}
}

ReactDOM.render(
<ConcurrentMode>
<Component />
</ConcurrentMode>,
container,
);
Scheduler.flushAll();

instance.setState({step: 1});
expect(container.textContent).toEqual('0');
Scheduler.flushAll();
expect(container.textContent).toEqual('1');
});

it('updates inside an async subtree are async by default', () => {
let instance;
class Child extends React.Component {
state = {step: 0};
render() {
instance = this;
return <div>{this.state.step}</div>;
}
}

ReactDOM.render(
<div>
<ConcurrentMode>
<Child />
</ConcurrentMode>
</div>,
container,
);
Scheduler.flushAll();

instance.setState({step: 1});
expect(container.textContent).toEqual('0');
Scheduler.flushAll();
expect(container.textContent).toEqual('1');
});

it('flushSync batches sync updates and flushes them at the end of the batch', () => {
let ops = [];
let instance;
Expand Down Expand Up @@ -345,12 +263,8 @@ describe('ReactDOMFiberAsync', () => {
}
}

ReactDOM.render(
<ConcurrentMode>
<Component />
</ConcurrentMode>,
container,
);
const root = ReactDOM.unstable_createRoot(container);
root.render(<Component />);
Scheduler.flushAll();

// Updates are async by default
Expand Down Expand Up @@ -390,12 +304,9 @@ describe('ReactDOMFiberAsync', () => {
return this.state.counter;
}
}
ReactDOM.render(
<ConcurrentMode>
<Counter />
</ConcurrentMode>,
container,
);
const root = ReactDOM.unstable_createRoot(container);
root.render(<Counter />);
Scheduler.flushAll();
expect(container.textContent).toEqual('0');

// Test that a normal update is async
Expand Down
8 changes: 2 additions & 6 deletions packages/react-dom/src/__tests__/ReactDOMHooks-test.js
Expand Up @@ -141,7 +141,7 @@ describe('ReactDOMHooks', () => {
expect(labelRef.current.innerHTML).toBe('abc');
});

it('should not bail out when an update is scheduled from within an event handler in ConcurrentMode', () => {
it('should not bail out when an update is scheduled from within an event handler in Concurrent Mode', () => {
const {createRef, useCallback, useState} = React;

const Example = ({inputRef, labelRef}) => {
Expand All @@ -162,11 +162,7 @@ describe('ReactDOMHooks', () => {
const labelRef = createRef();

const root = ReactDOM.unstable_createRoot(container);
root.render(
<React.unstable_ConcurrentMode>
<Example inputRef={inputRef} labelRef={labelRef} />
</React.unstable_ConcurrentMode>,
);
root.render(<Example inputRef={inputRef} labelRef={labelRef} />);

Scheduler.flushAll();

Expand Down
16 changes: 5 additions & 11 deletions packages/react-dom/src/__tests__/ReactDOMRoot-test.js
Expand Up @@ -13,7 +13,6 @@ let React = require('react');
let ReactDOM = require('react-dom');
let ReactDOMServer = require('react-dom/server');
let Scheduler = require('scheduler');
let ConcurrentMode = React.unstable_ConcurrentMode;

describe('ReactDOMRoot', () => {
let container;
Expand All @@ -25,7 +24,6 @@ describe('ReactDOMRoot', () => {
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');
Scheduler = require('scheduler');
ConcurrentMode = React.unstable_ConcurrentMode;
});

it('renders children', () => {
Expand All @@ -47,7 +45,7 @@ describe('ReactDOMRoot', () => {

it('`root.render` returns a thenable work object', () => {
const root = ReactDOM.unstable_createRoot(container);
const work = root.render(<ConcurrentMode>Hi</ConcurrentMode>);
const work = root.render('Hi');
let ops = [];
work.then(() => {
ops.push('inside callback: ' + container.textContent);
Expand All @@ -65,7 +63,7 @@ describe('ReactDOMRoot', () => {

it('resolves `work.then` callback synchronously if the work already committed', () => {
const root = ReactDOM.unstable_createRoot(container);
const work = root.render(<ConcurrentMode>Hi</ConcurrentMode>);
const work = root.render('Hi');
Scheduler.flushAll();
let ops = [];
work.then(() => {
Expand Down Expand Up @@ -157,11 +155,7 @@ describe('ReactDOMRoot', () => {

const root = ReactDOM.unstable_createRoot(container);
const batch = root.createBatch();
batch.render(
<ConcurrentMode>
<App />
</ConcurrentMode>,
);
batch.render(<App />);

Scheduler.flushAll();

Expand Down Expand Up @@ -208,7 +202,7 @@ describe('ReactDOMRoot', () => {
it('can wait for a batch to finish', () => {
const root = ReactDOM.unstable_createRoot(container);
const batch = root.createBatch();
batch.render(<ConcurrentMode>Foo</ConcurrentMode>);
batch.render('Foo');

Scheduler.flushAll();

Expand Down Expand Up @@ -248,7 +242,7 @@ describe('ReactDOMRoot', () => {

it('can commit an empty batch', () => {
const root = ReactDOM.unstable_createRoot(container);
root.render(<ConcurrentMode>1</ConcurrentMode>);
root.render(1);

Scheduler.advanceTime(2000);
// This batch has a later expiration time than the earlier update.
Expand Down
Expand Up @@ -103,72 +103,4 @@ describe('ReactDOMServerIntegration', () => {
expect(await render(<React.StrictMode />)).toBe(null);
});
});

describe('React.unstable_ConcurrentMode', () => {
itRenders('an concurrent mode with one child', async render => {
let e = await render(
<React.unstable_ConcurrentMode>
<div>text1</div>
</React.unstable_ConcurrentMode>,
);
let parent = e.parentNode;
expect(parent.childNodes[0].tagName).toBe('DIV');
});

itRenders('an concurrent mode with several children', async render => {
let Header = props => {
return <p>header</p>;
};
let Footer = props => {
return (
<React.unstable_ConcurrentMode>
<h2>footer</h2>
<h3>about</h3>
</React.unstable_ConcurrentMode>
);
};
let e = await render(
<React.unstable_ConcurrentMode>
<div>text1</div>
<span>text2</span>
<Header />
<Footer />
</React.unstable_ConcurrentMode>,
);
let parent = e.parentNode;
expect(parent.childNodes[0].tagName).toBe('DIV');
expect(parent.childNodes[1].tagName).toBe('SPAN');
expect(parent.childNodes[2].tagName).toBe('P');
expect(parent.childNodes[3].tagName).toBe('H2');
expect(parent.childNodes[4].tagName).toBe('H3');
});

itRenders('a nested concurrent mode', async render => {
let e = await render(
<React.unstable_ConcurrentMode>
<React.unstable_ConcurrentMode>
<div>text1</div>
</React.unstable_ConcurrentMode>
<span>text2</span>
<React.unstable_ConcurrentMode>
<React.unstable_ConcurrentMode>
<React.unstable_ConcurrentMode>
{null}
<p />
</React.unstable_ConcurrentMode>
{false}
</React.unstable_ConcurrentMode>
</React.unstable_ConcurrentMode>
</React.unstable_ConcurrentMode>,
);
let parent = e.parentNode;
expect(parent.childNodes[0].tagName).toBe('DIV');
expect(parent.childNodes[1].tagName).toBe('SPAN');
expect(parent.childNodes[2].tagName).toBe('P');
});

itRenders('an empty concurrent mode', async render => {
expect(await render(<React.unstable_ConcurrentMode />)).toBe(null);
});
});
});