Skip to content

Commit 4adfe2b

Browse files
committed
Make ART Concurrent if Legacy Mode is disabled
Updated flowing in from above as well as setStates will now be batched using "discrete" priority but should still happen same task. We need to use the right scheduler in tests for act to work properly.
1 parent 48ec17b commit 4adfe2b

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

packages/react-art/src/ReactART.js

+19-5
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@
77

88
import * as React from 'react';
99
import ReactVersion from 'shared/ReactVersion';
10-
import {LegacyRoot} from 'react-reconciler/src/ReactRootTags';
10+
import {LegacyRoot, ConcurrentRoot} from 'react-reconciler/src/ReactRootTags';
1111
import {
1212
createContainer,
1313
updateContainer,
1414
injectIntoDevTools,
15+
flushSync,
1516
} from 'react-reconciler/src/ReactFiberReconciler';
1617
import Transform from 'art/core/transform';
1718
import Mode from 'art/modes/current';
1819
import FastNoSideEffects from 'art/modes/fast-noSideEffects';
20+
import {disableLegacyMode} from 'shared/ReactFeatureFlags';
1921

2022
import {TYPES, childrenAsString} from './ReactARTInternals';
2123

@@ -68,13 +70,17 @@ class Surface extends React.Component {
6870

6971
this._mountNode = createContainer(
7072
this._surface,
71-
LegacyRoot,
73+
disableLegacyMode ? ConcurrentRoot : LegacyRoot,
7274
null,
7375
false,
7476
false,
7577
'',
7678
);
77-
updateContainer(this.props.children, this._mountNode, this);
79+
// We synchronously flush updates coming from above so that they commit together
80+
// and so that refs resolve before the parent life cycles.
81+
flushSync(() => {
82+
updateContainer(this.props.children, this._mountNode, this);
83+
});
7884
}
7985

8086
componentDidUpdate(prevProps, prevState) {
@@ -84,15 +90,23 @@ class Surface extends React.Component {
8490
this._surface.resize(+props.width, +props.height);
8591
}
8692

87-
updateContainer(this.props.children, this._mountNode, this);
93+
// We synchronously flush updates coming from above so that they commit together
94+
// and so that refs resolve before the parent life cycles.
95+
flushSync(() => {
96+
updateContainer(this.props.children, this._mountNode, this);
97+
});
8898

8999
if (this._surface.render) {
90100
this._surface.render();
91101
}
92102
}
93103

94104
componentWillUnmount() {
95-
updateContainer(null, this._mountNode, this);
105+
// We synchronously flush updates coming from above so that they commit together
106+
// and so that refs resolve before the parent life cycles.
107+
flushSync(() => {
108+
updateContainer(null, this._mountNode, this);
109+
});
96110
}
97111

98112
render() {

packages/react-art/src/__tests__/ReactART-test.js

+18-9
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111

1212
'use strict';
1313

14-
import * as React from 'react';
14+
const React = require('react');
15+
const Scheduler = require('scheduler');
1516

1617
import * as ReactART from 'react-art';
1718
import ARTSVGMode from 'art/modes/svg';
@@ -22,22 +23,27 @@ import Circle from 'react-art/Circle';
2223
import Rectangle from 'react-art/Rectangle';
2324
import Wedge from 'react-art/Wedge';
2425

26+
const {act, waitFor} = require('internal-test-utils');
27+
2528
// Isolate DOM renderer.
2629
jest.resetModules();
30+
// share isomorphic
31+
jest.mock('scheduler', () => Scheduler);
32+
jest.mock('react', () => React);
2733
const ReactDOMClient = require('react-dom/client');
28-
let act = require('internal-test-utils').act;
2934

3035
// Isolate the noop renderer
3136
jest.resetModules();
37+
// share isomorphic
38+
jest.mock('scheduler', () => Scheduler);
39+
jest.mock('react', () => React);
3240
const ReactNoop = require('react-noop-renderer');
33-
const Scheduler = require('scheduler');
3441

3542
let Group;
3643
let Shape;
3744
let Surface;
3845
let TestComponent;
3946

40-
let waitFor;
4147
let groupRef;
4248

4349
const Missing = {};
@@ -68,6 +74,11 @@ describe('ReactART', () => {
6874
let container;
6975

7076
beforeEach(() => {
77+
jest.resetModules();
78+
// share isomorphic
79+
jest.mock('scheduler', () => Scheduler);
80+
jest.mock('react', () => React);
81+
7182
container = document.createElement('div');
7283
document.body.appendChild(container);
7384

@@ -77,8 +88,6 @@ describe('ReactART', () => {
7788
Shape = ReactART.Shape;
7889
Surface = ReactART.Surface;
7990

80-
({waitFor} = require('internal-test-utils'));
81-
8291
groupRef = React.createRef();
8392
TestComponent = class extends React.Component {
8493
group = groupRef;
@@ -409,8 +418,6 @@ describe('ReactART', () => {
409418
);
410419
}
411420

412-
// Using test renderer instead of the DOM renderer here because async
413-
// testing APIs for the DOM renderer don't exist.
414421
ReactNoop.render(
415422
<CurrentRendererContext.Provider value="Test">
416423
<Yield value="A" />
@@ -447,9 +454,11 @@ describe('ReactARTComponents', () => {
447454
let ReactTestRenderer;
448455
beforeEach(() => {
449456
jest.resetModules();
457+
// share isomorphic
458+
jest.mock('scheduler', () => Scheduler);
459+
jest.mock('react', () => React);
450460
// Isolate test renderer.
451461
ReactTestRenderer = require('react-test-renderer');
452-
act = require('internal-test-utils').act;
453462
});
454463

455464
it('should generate a <Shape> with props for drawing the Circle', async () => {

0 commit comments

Comments
 (0)