From 0f3838a01b0fda0ac5fd054c6be13166697a113c Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Mon, 4 Nov 2019 14:07:05 -0800 Subject: [PATCH] Remove `debugRenderPhaseSideEffects` flag (#17270) There are two similar flags, `debugRenderPhaseSideEffects` and `debugRenderPhaseSideEffectsForStrictMode`. The strict mode one is the only one that is actually used. I think originally the theory is that we would one day turn it on for all components, even outside strict mode. But what we'll do instead is migrate everyone to strict mode. The only place `debugRenderPhaseSideEffects` was being used was in an internal test file. I rewrote those tests to use public APIs. --- .../src/ReactFiberBeginWork.js | 21 +- .../src/ReactFiberClassComponent.js | 11 +- .../react-reconciler/src/ReactUpdateQueue.js | 15 +- .../ReactDOMTracing-test.internal.js | 1 - .../__tests__/ReactProfiler-test.internal.js | 1 - .../ReactProfilerDOM-test.internal.js | 1 - .../ReactStrictMode-test.internal.js | 833 ------------------ .../src/__tests__/ReactStrictMode-test.js | 818 +++++++++++++++++ packages/shared/ReactFeatureFlags.js | 9 +- .../forks/ReactFeatureFlags.native-fb.js | 6 +- .../forks/ReactFeatureFlags.native-oss.js | 1 - .../forks/ReactFeatureFlags.persistent.js | 1 - .../forks/ReactFeatureFlags.test-renderer.js | 1 - .../ReactFeatureFlags.test-renderer.www.js | 1 - .../shared/forks/ReactFeatureFlags.www.js | 1 - 15 files changed, 839 insertions(+), 882 deletions(-) delete mode 100644 packages/react/src/__tests__/ReactStrictMode-test.internal.js diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.js b/packages/react-reconciler/src/ReactFiberBeginWork.js index cc51116413d6b..65bab16650151 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.js @@ -56,7 +56,6 @@ import { } from 'shared/ReactSideEffectTags'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import { - debugRenderPhaseSideEffects, debugRenderPhaseSideEffectsForStrictMode, disableLegacyContext, enableProfilerTimer, @@ -319,9 +318,8 @@ function updateForwardRef( renderExpirationTime, ); if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { @@ -642,9 +640,8 @@ function updateFunctionComponent( renderExpirationTime, ); if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { @@ -843,9 +840,8 @@ function finishClassComponent( setCurrentPhase('render'); nextChildren = instance.render(); if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode ) { instance.render(); } @@ -1376,9 +1372,8 @@ function mountIndeterminateComponent( } if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { diff --git a/packages/react-reconciler/src/ReactFiberClassComponent.js b/packages/react-reconciler/src/ReactFiberClassComponent.js index d00150d725079..8dc7e45835ea5 100644 --- a/packages/react-reconciler/src/ReactFiberClassComponent.js +++ b/packages/react-reconciler/src/ReactFiberClassComponent.js @@ -13,7 +13,6 @@ import type {ExpirationTime} from './ReactFiberExpirationTime'; import React from 'react'; import {Update, Snapshot} from 'shared/ReactSideEffectTags'; import { - debugRenderPhaseSideEffects, debugRenderPhaseSideEffectsForStrictMode, disableLegacyContext, warnAboutDeprecatedLifecycles, @@ -150,9 +149,8 @@ export function applyDerivedStateFromProps( if (__DEV__) { if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode ) { // Invoke the function an extra time to help detect side-effects. getDerivedStateFromProps(nextProps, prevState); @@ -605,9 +603,8 @@ function constructClassInstance( // Instantiate twice to help detect side-effects. if (__DEV__) { if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode ) { new ctor(props, context); // eslint-disable-line no-new } diff --git a/packages/react-reconciler/src/ReactUpdateQueue.js b/packages/react-reconciler/src/ReactUpdateQueue.js index bd3b73c5e9592..0d2a8f68230bf 100644 --- a/packages/react-reconciler/src/ReactUpdateQueue.js +++ b/packages/react-reconciler/src/ReactUpdateQueue.js @@ -97,10 +97,7 @@ import { import {Callback, ShouldCapture, DidCapture} from 'shared/ReactSideEffectTags'; import {ClassComponent} from 'shared/ReactWorkTags'; -import { - debugRenderPhaseSideEffects, - debugRenderPhaseSideEffectsForStrictMode, -} from 'shared/ReactFeatureFlags'; +import {debugRenderPhaseSideEffectsForStrictMode} from 'shared/ReactFeatureFlags'; import {StrictMode} from './ReactTypeOfMode'; import { @@ -373,9 +370,8 @@ function getStateFromUpdate( if (__DEV__) { enterDisallowedContextReadInDEV(); if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode ) { payload.call(instance, prevState, nextProps); } @@ -402,9 +398,8 @@ function getStateFromUpdate( if (__DEV__) { enterDisallowedContextReadInDEV(); if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode ) { payload.call(instance, prevState, nextProps); } diff --git a/packages/react/src/__tests__/ReactDOMTracing-test.internal.js b/packages/react/src/__tests__/ReactDOMTracing-test.internal.js index b2684352a6154..75e25205de18e 100644 --- a/packages/react/src/__tests__/ReactDOMTracing-test.internal.js +++ b/packages/react/src/__tests__/ReactDOMTracing-test.internal.js @@ -25,7 +25,6 @@ let onWorkStopped; function loadModules() { ReactFeatureFlags = require('shared/ReactFeatureFlags'); - ReactFeatureFlags.debugRenderPhaseSideEffects = false; ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false; ReactFeatureFlags.enableProfilerTimer = true; ReactFeatureFlags.enableSchedulerTracing = true; diff --git a/packages/react/src/__tests__/ReactProfiler-test.internal.js b/packages/react/src/__tests__/ReactProfiler-test.internal.js index 150573b4950d0..ba29d2acc58f3 100644 --- a/packages/react/src/__tests__/ReactProfiler-test.internal.js +++ b/packages/react/src/__tests__/ReactProfiler-test.internal.js @@ -30,7 +30,6 @@ function loadModules({ useNoopRenderer = false, } = {}) { ReactFeatureFlags = require('shared/ReactFeatureFlags'); - ReactFeatureFlags.debugRenderPhaseSideEffects = false; ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false; ReactFeatureFlags.enableProfilerTimer = enableProfilerTimer; ReactFeatureFlags.enableSchedulerTracing = enableSchedulerTracing; diff --git a/packages/react/src/__tests__/ReactProfilerDOM-test.internal.js b/packages/react/src/__tests__/ReactProfilerDOM-test.internal.js index d60a12b64947c..1152818abc191 100644 --- a/packages/react/src/__tests__/ReactProfilerDOM-test.internal.js +++ b/packages/react/src/__tests__/ReactProfilerDOM-test.internal.js @@ -17,7 +17,6 @@ let Scheduler; function loadModules() { ReactFeatureFlags = require('shared/ReactFeatureFlags'); - ReactFeatureFlags.debugRenderPhaseSideEffects = false; ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false; ReactFeatureFlags.enableProfilerTimer = true; ReactFeatureFlags.enableSchedulerTracing = true; diff --git a/packages/react/src/__tests__/ReactStrictMode-test.internal.js b/packages/react/src/__tests__/ReactStrictMode-test.internal.js deleted file mode 100644 index 8dea81c71d528..0000000000000 --- a/packages/react/src/__tests__/ReactStrictMode-test.internal.js +++ /dev/null @@ -1,833 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @emails react-core - */ - -'use strict'; - -let React; -let Scheduler; -let ReactFeatureFlags; -let ReactTestRenderer; -let PropTypes; - -describe('ReactStrictMode', () => { - describe('debugRenderPhaseSideEffects', () => { - beforeEach(() => { - jest.resetModules(); - ReactFeatureFlags = require('shared/ReactFeatureFlags'); - ReactFeatureFlags.debugRenderPhaseSideEffects = true; - React = require('react'); - Scheduler = require('scheduler'); - ReactTestRenderer = require('react-test-renderer'); - }); - - it('should invoke precommit lifecycle methods twice', () => { - let log = []; - let shouldComponentUpdate = false; - class ClassComponent extends React.Component { - state = {}; - static getDerivedStateFromProps() { - log.push('getDerivedStateFromProps'); - return null; - } - constructor(props) { - super(props); - log.push('constructor'); - } - componentDidMount() { - log.push('componentDidMount'); - } - componentDidUpdate() { - log.push('componentDidUpdate'); - } - componentWillUnmount() { - log.push('componentWillUnmount'); - } - shouldComponentUpdate() { - log.push('shouldComponentUpdate'); - return shouldComponentUpdate; - } - render() { - log.push('render'); - return null; - } - } - - const component = ReactTestRenderer.create(); - - if (__DEV__) { - expect(log).toEqual([ - 'constructor', - 'constructor', - 'getDerivedStateFromProps', - 'getDerivedStateFromProps', - 'render', - 'render', - 'componentDidMount', - ]); - } else { - expect(log).toEqual([ - 'constructor', - 'getDerivedStateFromProps', - 'render', - 'componentDidMount', - ]); - } - - log = []; - shouldComponentUpdate = true; - - component.update(); - if (__DEV__) { - expect(log).toEqual([ - 'getDerivedStateFromProps', - 'getDerivedStateFromProps', - 'shouldComponentUpdate', - 'render', - 'render', - 'componentDidUpdate', - ]); - } else { - expect(log).toEqual([ - 'getDerivedStateFromProps', - 'shouldComponentUpdate', - 'render', - 'componentDidUpdate', - ]); - } - - log = []; - shouldComponentUpdate = false; - - component.update(); - - if (__DEV__) { - expect(log).toEqual([ - 'getDerivedStateFromProps', - 'getDerivedStateFromProps', - 'shouldComponentUpdate', - ]); - } else { - expect(log).toEqual([ - 'getDerivedStateFromProps', - 'shouldComponentUpdate', - ]); - } - }); - - it('should invoke setState callbacks twice', () => { - class ClassComponent extends React.Component { - state = { - count: 1, - }; - render() { - return null; - } - } - - let setStateCount = 0; - - const rendered = ReactTestRenderer.create(); - const instance = rendered.getInstance(); - instance.setState(state => { - setStateCount++; - return { - count: state.count + 1, - }; - }); - - // Callback should be invoked twice in DEV - expect(setStateCount).toBe(__DEV__ ? 2 : 1); - // But each time `state` should be the previous value - expect(instance.state.count).toBe(2); - }); - }); - - [true, false].forEach(debugRenderPhaseSideEffectsForStrictMode => { - describe(`StrictMode (${debugRenderPhaseSideEffectsForStrictMode})`, () => { - beforeEach(() => { - jest.resetModules(); - ReactFeatureFlags = require('shared/ReactFeatureFlags'); - ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = debugRenderPhaseSideEffectsForStrictMode; - React = require('react'); - Scheduler = require('scheduler'); - ReactTestRenderer = require('react-test-renderer'); - }); - - it('should invoke precommit lifecycle methods twice in DEV', () => { - const {StrictMode} = React; - - let log = []; - let shouldComponentUpdate = false; - - function Root() { - return ( - - - - ); - } - - class ClassComponent extends React.Component { - state = {}; - static getDerivedStateFromProps() { - log.push('getDerivedStateFromProps'); - return null; - } - constructor(props) { - super(props); - log.push('constructor'); - } - componentDidMount() { - log.push('componentDidMount'); - } - componentDidUpdate() { - log.push('componentDidUpdate'); - } - componentWillUnmount() { - log.push('componentWillUnmount'); - } - shouldComponentUpdate() { - log.push('shouldComponentUpdate'); - return shouldComponentUpdate; - } - render() { - log.push('render'); - return null; - } - } - - const component = ReactTestRenderer.create(); - - if (__DEV__ && debugRenderPhaseSideEffectsForStrictMode) { - expect(log).toEqual([ - 'constructor', - 'constructor', - 'getDerivedStateFromProps', - 'getDerivedStateFromProps', - 'render', - 'render', - 'componentDidMount', - ]); - } else { - expect(log).toEqual([ - 'constructor', - 'getDerivedStateFromProps', - 'render', - 'componentDidMount', - ]); - } - - log = []; - shouldComponentUpdate = true; - - component.update(); - if (__DEV__ && debugRenderPhaseSideEffectsForStrictMode) { - expect(log).toEqual([ - 'getDerivedStateFromProps', - 'getDerivedStateFromProps', - 'shouldComponentUpdate', - 'render', - 'render', - 'componentDidUpdate', - ]); - } else { - expect(log).toEqual([ - 'getDerivedStateFromProps', - 'shouldComponentUpdate', - 'render', - 'componentDidUpdate', - ]); - } - - log = []; - shouldComponentUpdate = false; - - component.update(); - if (__DEV__ && debugRenderPhaseSideEffectsForStrictMode) { - expect(log).toEqual([ - 'getDerivedStateFromProps', - 'getDerivedStateFromProps', - 'shouldComponentUpdate', - ]); - } else { - expect(log).toEqual([ - 'getDerivedStateFromProps', - 'shouldComponentUpdate', - ]); - } - }); - - it('should invoke setState callbacks twice in DEV', () => { - const {StrictMode} = React; - - let instance; - class ClassComponent extends React.Component { - state = { - count: 1, - }; - render() { - instance = this; - return null; - } - } - - let setStateCount = 0; - - ReactTestRenderer.create( - - - , - ); - instance.setState(state => { - setStateCount++; - return { - count: state.count + 1, - }; - }); - - // Callback should be invoked twice (in DEV) - expect(setStateCount).toBe( - __DEV__ && debugRenderPhaseSideEffectsForStrictMode ? 2 : 1, - ); - // But each time `state` should be the previous value - expect(instance.state.count).toBe(2); - }); - }); - }); - - describe('Concurrent Mode', () => { - beforeEach(() => { - jest.resetModules(); - - React = require('react'); - Scheduler = require('scheduler'); - ReactTestRenderer = require('react-test-renderer'); - }); - - it('should warn about unsafe legacy lifecycle methods anywhere in the tree', () => { - class AsyncRoot extends React.Component { - UNSAFE_componentWillMount() {} - UNSAFE_componentWillUpdate() {} - render() { - return ( -
- - - -
- - -
-
- ); - } - } - function Wrapper({children}) { - return
{children}
; - } - class Foo extends React.Component { - UNSAFE_componentWillReceiveProps() {} - render() { - return null; - } - } - class Bar extends React.Component { - UNSAFE_componentWillReceiveProps() {} - render() { - return null; - } - } - - const root = ReactTestRenderer.create(null, { - unstable_isConcurrent: true, - }); - root.update(); - expect(() => Scheduler.unstable_flushAll()).toWarnDev( - [ - /* eslint-disable max-len */ - `Warning: Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. - -* Move code with side effects to componentDidMount, and set initial state in the constructor. - -Please update the following components: AsyncRoot`, - `Warning: Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. - -* Move data fetching code or side effects to componentDidUpdate. -* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state - -Please update the following components: Bar, Foo`, - `Warning: Using UNSAFE_componentWillUpdate in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. - -* Move data fetching code or side effects to componentDidUpdate. - -Please update the following components: AsyncRoot`, - /* eslint-enable max-len */ - ], - {withoutStack: true}, - ); - - // Dedupe - root.update(); - Scheduler.unstable_flushAll(); - }); - - it('should coalesce warnings by lifecycle name', () => { - class AsyncRoot extends React.Component { - UNSAFE_componentWillMount() {} - UNSAFE_componentWillUpdate() {} - render() { - return ; - } - } - class Parent extends React.Component { - componentWillMount() {} - componentWillUpdate() {} - componentWillReceiveProps() {} - render() { - return ; - } - } - class Child extends React.Component { - UNSAFE_componentWillReceiveProps() {} - render() { - return null; - } - } - - const root = ReactTestRenderer.create(null, { - unstable_isConcurrent: true, - }); - root.update(); - - expect(() => { - expect(() => Scheduler.unstable_flushAll()).toWarnDev( - [ - /* eslint-disable max-len */ - `Warning: Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. - -* Move code with side effects to componentDidMount, and set initial state in the constructor. - -Please update the following components: AsyncRoot`, - `Warning: Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. - -* Move data fetching code or side effects to componentDidUpdate. -* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state - -Please update the following components: Child`, - `Warning: Using UNSAFE_componentWillUpdate in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. - -* Move data fetching code or side effects to componentDidUpdate. - -Please update the following components: AsyncRoot`, - /* eslint-enable max-len */ - ], - {withoutStack: true}, - ); - }).toLowPriorityWarnDev( - [ - /* eslint-disable max-len */ - `Warning: componentWillMount has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details. - -* Move code with side effects to componentDidMount, and set initial state in the constructor. -* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder. - -Please update the following components: Parent`, - `Warning: componentWillReceiveProps has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details. - -* Move data fetching code or side effects to componentDidUpdate. -* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state -* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder. - -Please update the following components: Parent`, - `Warning: componentWillUpdate has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details. - -* Move data fetching code or side effects to componentDidUpdate. -* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder. - -Please update the following components: Parent`, - /* eslint-enable max-len */ - ], - {withoutStack: true}, - ); - // Dedupe - root.update(); - Scheduler.unstable_flushAll(); - }); - - it('should warn about components not present during the initial render', () => { - class AsyncRoot extends React.Component { - render() { - return this.props.foo ? : ; - } - } - class Foo extends React.Component { - UNSAFE_componentWillMount() {} - render() { - return null; - } - } - class Bar extends React.Component { - UNSAFE_componentWillMount() {} - render() { - return null; - } - } - - const root = ReactTestRenderer.create(null, { - unstable_isConcurrent: true, - }); - root.update(); - expect(() => Scheduler.unstable_flushAll()).toWarnDev( - 'Using UNSAFE_componentWillMount in strict mode is not recommended', - {withoutStack: true}, - ); - - root.update(); - expect(() => Scheduler.unstable_flushAll()).toWarnDev( - 'Using UNSAFE_componentWillMount in strict mode is not recommended', - {withoutStack: true}, - ); - - // Dedupe - root.update(); - Scheduler.unstable_flushAll(); - root.update(); - Scheduler.unstable_flushAll(); - }); - - it('should also warn inside of "strict" mode trees', () => { - const {StrictMode} = React; - - class SyncRoot extends React.Component { - UNSAFE_componentWillMount() {} - UNSAFE_componentWillUpdate() {} - UNSAFE_componentWillReceiveProps() {} - render() { - return ( - - - - ); - } - } - function Wrapper({children}) { - return ( -
- - -
- ); - } - class Foo extends React.Component { - UNSAFE_componentWillReceiveProps() {} - render() { - return null; - } - } - class Bar extends React.Component { - UNSAFE_componentWillReceiveProps() {} - render() { - return null; - } - } - - expect(() => ReactTestRenderer.create()).toWarnDev( - 'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended', - {withoutStack: true}, - ); - - // Dedupe - const rendered = ReactTestRenderer.create(); - rendered.update(); - }); - }); - - describe('symbol checks', () => { - beforeEach(() => { - jest.resetModules(); - React = require('react'); - ReactTestRenderer = require('react-test-renderer'); - }); - - it('should switch from StrictMode to a Fragment and reset state', () => { - const {Fragment, StrictMode} = React; - - function ParentComponent({useFragment}) { - return useFragment ? ( - - - - ) : ( - - - - ); - } - - class ChildComponent extends React.Component { - state = { - count: 0, - }; - static getDerivedStateFromProps(nextProps, prevState) { - return { - count: prevState.count + 1, - }; - } - render() { - return `count:${this.state.count}`; - } - } - - const rendered = ReactTestRenderer.create( - , - ); - expect(rendered.toJSON()).toBe('count:1'); - rendered.update(); - expect(rendered.toJSON()).toBe('count:1'); - }); - - it('should switch from a Fragment to StrictMode and reset state', () => { - const {Fragment, StrictMode} = React; - - function ParentComponent({useFragment}) { - return useFragment ? ( - - - - ) : ( - - - - ); - } - - class ChildComponent extends React.Component { - state = { - count: 0, - }; - static getDerivedStateFromProps(nextProps, prevState) { - return { - count: prevState.count + 1, - }; - } - render() { - return `count:${this.state.count}`; - } - } - - const rendered = ReactTestRenderer.create( - , - ); - expect(rendered.toJSON()).toBe('count:1'); - rendered.update(); - expect(rendered.toJSON()).toBe('count:1'); - }); - - it('should update with StrictMode without losing state', () => { - const {StrictMode} = React; - - function ParentComponent() { - return ( - - - - ); - } - - class ChildComponent extends React.Component { - state = { - count: 0, - }; - static getDerivedStateFromProps(nextProps, prevState) { - return { - count: prevState.count + 1, - }; - } - render() { - return `count:${this.state.count}`; - } - } - - const rendered = ReactTestRenderer.create(); - expect(rendered.toJSON()).toBe('count:1'); - rendered.update(); - expect(rendered.toJSON()).toBe('count:2'); - }); - }); - - describe('string refs', () => { - beforeEach(() => { - jest.resetModules(); - React = require('react'); - ReactTestRenderer = require('react-test-renderer'); - }); - - it('should warn within a strict tree', () => { - const {StrictMode} = React; - - class OuterComponent extends React.Component { - render() { - return ( - - - - ); - } - } - - class InnerComponent extends React.Component { - render() { - return null; - } - } - - let renderer; - expect(() => { - renderer = ReactTestRenderer.create(); - }).toWarnDev( - 'Warning: A string ref, "somestring", has been found within a strict mode tree. ' + - 'String refs are a source of potential bugs and should be avoided. ' + - 'We recommend using useRef() or createRef() instead. ' + - 'Learn more about using refs safely here: ' + - 'https://fb.me/react-strict-mode-string-ref\n' + - ' in StrictMode (at **)\n' + - ' in OuterComponent (at **)', - ); - - // Dedup - renderer.update(); - }); - - it('should warn within a strict tree', () => { - const {StrictMode} = React; - - class OuterComponent extends React.Component { - render() { - return ( - - - - ); - } - } - - class InnerComponent extends React.Component { - render() { - return ; - } - } - - class MiddleComponent extends React.Component { - render() { - return null; - } - } - - let renderer; - expect(() => { - renderer = ReactTestRenderer.create(); - }).toWarnDev( - 'Warning: A string ref, "somestring", has been found within a strict mode tree. ' + - 'String refs are a source of potential bugs and should be avoided. ' + - 'We recommend using useRef() or createRef() instead. ' + - 'Learn more about using refs safely here: ' + - 'https://fb.me/react-strict-mode-string-ref\n' + - ' in InnerComponent (at **)\n' + - ' in StrictMode (at **)\n' + - ' in OuterComponent (at **)', - ); - - // Dedup - renderer.update(); - }); - }); - - describe('context legacy', () => { - beforeEach(() => { - jest.resetModules(); - React = require('react'); - ReactTestRenderer = require('react-test-renderer'); - PropTypes = require('prop-types'); - }); - - it('should warn if the legacy context API have been used in strict mode', () => { - class LegacyContextProvider extends React.Component { - getChildContext() { - return {color: 'purple'}; - } - - render() { - return ( -
- - -
- ); - } - } - - function FunctionalLegacyContextConsumer() { - return null; - } - - LegacyContextProvider.childContextTypes = { - color: PropTypes.string, - }; - - class LegacyContextConsumer extends React.Component { - render() { - return null; - } - } - - const {StrictMode} = React; - - class Root extends React.Component { - render() { - return ( -
- - - -
- ); - } - } - - LegacyContextConsumer.contextTypes = { - color: PropTypes.string, - }; - - FunctionalLegacyContextConsumer.contextTypes = { - color: PropTypes.string, - }; - - let rendered; - - expect(() => { - rendered = ReactTestRenderer.create(); - }).toWarnDev( - 'Warning: Legacy context API has been detected within a strict-mode tree.' + - '\n\nThe old API will be supported in all 16.x releases, but applications ' + - 'using it should migrate to the new version.' + - '\n\nPlease update the following components: ' + - 'FunctionalLegacyContextConsumer, LegacyContextConsumer, LegacyContextProvider' + - '\n\nLearn more about this warning here: ' + - 'https://fb.me/react-legacy-context' + - '\n in StrictMode (at **)' + - '\n in div (at **)' + - '\n in Root (at **)', - ); - - // Dedupe - rendered = ReactTestRenderer.create(); - rendered.update(); - }); - }); -}); diff --git a/packages/react/src/__tests__/ReactStrictMode-test.js b/packages/react/src/__tests__/ReactStrictMode-test.js index 53850a0b81684..07e7b1bd78c16 100644 --- a/packages/react/src/__tests__/ReactStrictMode-test.js +++ b/packages/react/src/__tests__/ReactStrictMode-test.js @@ -12,6 +12,8 @@ let React; let ReactDOM; let ReactDOMServer; +let Scheduler; +let PropTypes; describe('ReactStrictMode', () => { beforeEach(() => { @@ -62,4 +64,820 @@ describe('ReactStrictMode', () => { ' in StrictMode (at **)', ); }); + + it('should invoke precommit lifecycle methods twice', () => { + let log = []; + let shouldComponentUpdate = false; + class ClassComponent extends React.Component { + state = {}; + static getDerivedStateFromProps() { + log.push('getDerivedStateFromProps'); + return null; + } + constructor(props) { + super(props); + log.push('constructor'); + } + componentDidMount() { + log.push('componentDidMount'); + } + componentDidUpdate() { + log.push('componentDidUpdate'); + } + componentWillUnmount() { + log.push('componentWillUnmount'); + } + shouldComponentUpdate() { + log.push('shouldComponentUpdate'); + return shouldComponentUpdate; + } + render() { + log.push('render'); + return null; + } + } + + const container = document.createElement('div'); + ReactDOM.render( + + + , + container, + ); + + if (__DEV__) { + expect(log).toEqual([ + 'constructor', + 'constructor', + 'getDerivedStateFromProps', + 'getDerivedStateFromProps', + 'render', + 'render', + 'componentDidMount', + ]); + } else { + expect(log).toEqual([ + 'constructor', + 'getDerivedStateFromProps', + 'render', + 'componentDidMount', + ]); + } + + log = []; + shouldComponentUpdate = true; + + ReactDOM.render( + + + , + container, + ); + if (__DEV__) { + expect(log).toEqual([ + 'getDerivedStateFromProps', + 'getDerivedStateFromProps', + 'shouldComponentUpdate', + 'render', + 'render', + 'componentDidUpdate', + ]); + } else { + expect(log).toEqual([ + 'getDerivedStateFromProps', + 'shouldComponentUpdate', + 'render', + 'componentDidUpdate', + ]); + } + + log = []; + shouldComponentUpdate = false; + + ReactDOM.render( + + + , + container, + ); + + if (__DEV__) { + expect(log).toEqual([ + 'getDerivedStateFromProps', + 'getDerivedStateFromProps', + 'shouldComponentUpdate', + ]); + } else { + expect(log).toEqual([ + 'getDerivedStateFromProps', + 'shouldComponentUpdate', + ]); + } + }); + + it('should invoke setState callbacks twice', () => { + let instance; + class ClassComponent extends React.Component { + state = { + count: 1, + }; + render() { + instance = this; + return null; + } + } + + let setStateCount = 0; + + const container = document.createElement('div'); + ReactDOM.render( + + + , + container, + ); + instance.setState(state => { + setStateCount++; + return { + count: state.count + 1, + }; + }); + + // Callback should be invoked twice in DEV + expect(setStateCount).toBe(__DEV__ ? 2 : 1); + // But each time `state` should be the previous value + expect(instance.state.count).toBe(2); + }); + + it('should invoke precommit lifecycle methods twice in DEV', () => { + const {StrictMode} = React; + + let log = []; + let shouldComponentUpdate = false; + + function Root() { + return ( + + + + ); + } + + class ClassComponent extends React.Component { + state = {}; + static getDerivedStateFromProps() { + log.push('getDerivedStateFromProps'); + return null; + } + constructor(props) { + super(props); + log.push('constructor'); + } + componentDidMount() { + log.push('componentDidMount'); + } + componentDidUpdate() { + log.push('componentDidUpdate'); + } + componentWillUnmount() { + log.push('componentWillUnmount'); + } + shouldComponentUpdate() { + log.push('shouldComponentUpdate'); + return shouldComponentUpdate; + } + render() { + log.push('render'); + return null; + } + } + + const container = document.createElement('div'); + ReactDOM.render(, container); + + if (__DEV__) { + expect(log).toEqual([ + 'constructor', + 'constructor', + 'getDerivedStateFromProps', + 'getDerivedStateFromProps', + 'render', + 'render', + 'componentDidMount', + ]); + } else { + expect(log).toEqual([ + 'constructor', + 'getDerivedStateFromProps', + 'render', + 'componentDidMount', + ]); + } + + log = []; + shouldComponentUpdate = true; + + ReactDOM.render(, container); + if (__DEV__) { + expect(log).toEqual([ + 'getDerivedStateFromProps', + 'getDerivedStateFromProps', + 'shouldComponentUpdate', + 'render', + 'render', + 'componentDidUpdate', + ]); + } else { + expect(log).toEqual([ + 'getDerivedStateFromProps', + 'shouldComponentUpdate', + 'render', + 'componentDidUpdate', + ]); + } + + log = []; + shouldComponentUpdate = false; + + ReactDOM.render(, container); + if (__DEV__) { + expect(log).toEqual([ + 'getDerivedStateFromProps', + 'getDerivedStateFromProps', + 'shouldComponentUpdate', + ]); + } else { + expect(log).toEqual([ + 'getDerivedStateFromProps', + 'shouldComponentUpdate', + ]); + } + }); + + it('should invoke setState callbacks twice in DEV', () => { + const {StrictMode} = React; + + let instance; + class ClassComponent extends React.Component { + state = { + count: 1, + }; + render() { + instance = this; + return null; + } + } + + let setStateCount = 0; + + const container = document.createElement('div'); + ReactDOM.render( + + + , + container, + ); + instance.setState(state => { + setStateCount++; + return { + count: state.count + 1, + }; + }); + + // Callback should be invoked twice (in DEV) + expect(setStateCount).toBe(__DEV__ ? 2 : 1); + // But each time `state` should be the previous value + expect(instance.state.count).toBe(2); + }); +}); + +describe('Concurrent Mode', () => { + beforeEach(() => { + jest.resetModules(); + + React = require('react'); + ReactDOM = require('react-dom'); + Scheduler = require('scheduler'); + }); + + it.experimental( + 'should warn about unsafe legacy lifecycle methods anywhere in the tree', + () => { + class AsyncRoot extends React.Component { + UNSAFE_componentWillMount() {} + UNSAFE_componentWillUpdate() {} + render() { + return ( +
+ + + +
+ + +
+
+ ); + } + } + function Wrapper({children}) { + return
{children}
; + } + class Foo extends React.Component { + UNSAFE_componentWillReceiveProps() {} + render() { + return null; + } + } + class Bar extends React.Component { + UNSAFE_componentWillReceiveProps() {} + render() { + return null; + } + } + + const container = document.createElement('div'); + const root = ReactDOM.createRoot(container); + root.render(); + expect(() => Scheduler.unstable_flushAll()).toWarnDev( + [ + /* eslint-disable max-len */ + `Warning: Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move code with side effects to componentDidMount, and set initial state in the constructor. + +Please update the following components: AsyncRoot`, + `Warning: Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move data fetching code or side effects to componentDidUpdate. +* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state + +Please update the following components: Bar, Foo`, + `Warning: Using UNSAFE_componentWillUpdate in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move data fetching code or side effects to componentDidUpdate. + +Please update the following components: AsyncRoot`, + /* eslint-enable max-len */ + ], + {withoutStack: true}, + ); + + // Dedupe + root.render(); + Scheduler.unstable_flushAll(); + }, + ); + + it.experimental('should coalesce warnings by lifecycle name', () => { + class AsyncRoot extends React.Component { + UNSAFE_componentWillMount() {} + UNSAFE_componentWillUpdate() {} + render() { + return ; + } + } + class Parent extends React.Component { + componentWillMount() {} + componentWillUpdate() {} + componentWillReceiveProps() {} + render() { + return ; + } + } + class Child extends React.Component { + UNSAFE_componentWillReceiveProps() {} + render() { + return null; + } + } + + const container = document.createElement('div'); + const root = ReactDOM.createRoot(container); + root.render(); + + expect(() => { + expect(() => Scheduler.unstable_flushAll()).toWarnDev( + [ + /* eslint-disable max-len */ + `Warning: Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move code with side effects to componentDidMount, and set initial state in the constructor. + +Please update the following components: AsyncRoot`, + `Warning: Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move data fetching code or side effects to componentDidUpdate. +* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state + +Please update the following components: Child`, + `Warning: Using UNSAFE_componentWillUpdate in strict mode is not recommended and may indicate bugs in your code. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move data fetching code or side effects to componentDidUpdate. + +Please update the following components: AsyncRoot`, + /* eslint-enable max-len */ + ], + {withoutStack: true}, + ); + }).toLowPriorityWarnDev( + [ + /* eslint-disable max-len */ + `Warning: componentWillMount has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move code with side effects to componentDidMount, and set initial state in the constructor. +* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder. + +Please update the following components: Parent`, + `Warning: componentWillReceiveProps has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move data fetching code or side effects to componentDidUpdate. +* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state +* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder. + +Please update the following components: Parent`, + `Warning: componentWillUpdate has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details. + +* Move data fetching code or side effects to componentDidUpdate. +* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder. + +Please update the following components: Parent`, + /* eslint-enable max-len */ + ], + {withoutStack: true}, + ); + // Dedupe + root.render(); + Scheduler.unstable_flushAll(); + }); + + it.experimental( + 'should warn about components not present during the initial render', + () => { + class AsyncRoot extends React.Component { + render() { + return this.props.foo ? : ; + } + } + class Foo extends React.Component { + UNSAFE_componentWillMount() {} + render() { + return null; + } + } + class Bar extends React.Component { + UNSAFE_componentWillMount() {} + render() { + return null; + } + } + + const container = document.createElement('div'); + const root = ReactDOM.createRoot(container); + root.render(); + expect(() => Scheduler.unstable_flushAll()).toWarnDev( + 'Using UNSAFE_componentWillMount in strict mode is not recommended', + {withoutStack: true}, + ); + + root.render(); + expect(() => Scheduler.unstable_flushAll()).toWarnDev( + 'Using UNSAFE_componentWillMount in strict mode is not recommended', + {withoutStack: true}, + ); + + // Dedupe + root.render(); + Scheduler.unstable_flushAll(); + root.render(); + Scheduler.unstable_flushAll(); + }, + ); + + it('should also warn inside of "strict" mode trees', () => { + const {StrictMode} = React; + + class SyncRoot extends React.Component { + UNSAFE_componentWillMount() {} + UNSAFE_componentWillUpdate() {} + UNSAFE_componentWillReceiveProps() {} + render() { + return ( + + + + ); + } + } + function Wrapper({children}) { + return ( +
+ + +
+ ); + } + class Foo extends React.Component { + UNSAFE_componentWillReceiveProps() {} + render() { + return null; + } + } + class Bar extends React.Component { + UNSAFE_componentWillReceiveProps() {} + render() { + return null; + } + } + + const container = document.createElement('div'); + + expect(() => ReactDOM.render(, container)).toWarnDev( + 'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended', + {withoutStack: true}, + ); + + // Dedupe + ReactDOM.render(, container); + }); +}); + +describe('symbol checks', () => { + beforeEach(() => { + jest.resetModules(); + React = require('react'); + ReactDOM = require('react-dom'); + }); + + it('should switch from StrictMode to a Fragment and reset state', () => { + const {Fragment, StrictMode} = React; + + function ParentComponent({useFragment}) { + return useFragment ? ( + + + + ) : ( + + + + ); + } + + class ChildComponent extends React.Component { + state = { + count: 0, + }; + static getDerivedStateFromProps(nextProps, prevState) { + return { + count: prevState.count + 1, + }; + } + render() { + return `count:${this.state.count}`; + } + } + + const container = document.createElement('div'); + ReactDOM.render(, container); + expect(container.textContent).toBe('count:1'); + ReactDOM.render(, container); + expect(container.textContent).toBe('count:1'); + }); + + it('should switch from a Fragment to StrictMode and reset state', () => { + const {Fragment, StrictMode} = React; + + function ParentComponent({useFragment}) { + return useFragment ? ( + + + + ) : ( + + + + ); + } + + class ChildComponent extends React.Component { + state = { + count: 0, + }; + static getDerivedStateFromProps(nextProps, prevState) { + return { + count: prevState.count + 1, + }; + } + render() { + return `count:${this.state.count}`; + } + } + + const container = document.createElement('div'); + ReactDOM.render(, container); + expect(container.textContent).toBe('count:1'); + ReactDOM.render(, container); + expect(container.textContent).toBe('count:1'); + }); + + it('should update with StrictMode without losing state', () => { + const {StrictMode} = React; + + function ParentComponent() { + return ( + + + + ); + } + + class ChildComponent extends React.Component { + state = { + count: 0, + }; + static getDerivedStateFromProps(nextProps, prevState) { + return { + count: prevState.count + 1, + }; + } + render() { + return `count:${this.state.count}`; + } + } + + const container = document.createElement('div'); + ReactDOM.render(, container); + expect(container.textContent).toBe('count:1'); + ReactDOM.render(, container); + expect(container.textContent).toBe('count:2'); + }); +}); + +describe('string refs', () => { + beforeEach(() => { + jest.resetModules(); + React = require('react'); + ReactDOM = require('react-dom'); + }); + + it('should warn within a strict tree', () => { + const {StrictMode} = React; + + class OuterComponent extends React.Component { + render() { + return ( + + + + ); + } + } + + class InnerComponent extends React.Component { + render() { + return null; + } + } + + const container = document.createElement('div'); + expect(() => { + ReactDOM.render(, container); + }).toWarnDev( + 'Warning: A string ref, "somestring", has been found within a strict mode tree. ' + + 'String refs are a source of potential bugs and should be avoided. ' + + 'We recommend using useRef() or createRef() instead. ' + + 'Learn more about using refs safely here: ' + + 'https://fb.me/react-strict-mode-string-ref\n' + + ' in StrictMode (at **)\n' + + ' in OuterComponent (at **)', + ); + + // Dedup + ReactDOM.render(, container); + }); + + it('should warn within a strict tree', () => { + const {StrictMode} = React; + + class OuterComponent extends React.Component { + render() { + return ( + + + + ); + } + } + + class InnerComponent extends React.Component { + render() { + return ; + } + } + + class MiddleComponent extends React.Component { + render() { + return null; + } + } + + const container = document.createElement('div'); + expect(() => { + ReactDOM.render(, container); + }).toWarnDev( + 'Warning: A string ref, "somestring", has been found within a strict mode tree. ' + + 'String refs are a source of potential bugs and should be avoided. ' + + 'We recommend using useRef() or createRef() instead. ' + + 'Learn more about using refs safely here: ' + + 'https://fb.me/react-strict-mode-string-ref\n' + + ' in InnerComponent (at **)\n' + + ' in StrictMode (at **)\n' + + ' in OuterComponent (at **)', + ); + + // Dedup + ReactDOM.render(, container); + }); +}); + +describe('context legacy', () => { + beforeEach(() => { + jest.resetModules(); + React = require('react'); + ReactDOM = require('react-dom'); + PropTypes = require('prop-types'); + }); + + it('should warn if the legacy context API have been used in strict mode', () => { + class LegacyContextProvider extends React.Component { + getChildContext() { + return {color: 'purple'}; + } + + render() { + return ( +
+ + +
+ ); + } + } + + function FunctionalLegacyContextConsumer() { + return null; + } + + LegacyContextProvider.childContextTypes = { + color: PropTypes.string, + }; + + class LegacyContextConsumer extends React.Component { + render() { + return null; + } + } + + const {StrictMode} = React; + + class Root extends React.Component { + render() { + return ( +
+ + + +
+ ); + } + } + + LegacyContextConsumer.contextTypes = { + color: PropTypes.string, + }; + + FunctionalLegacyContextConsumer.contextTypes = { + color: PropTypes.string, + }; + + const container = document.createElement('div'); + expect(() => { + ReactDOM.render(, container); + }).toWarnDev( + 'Warning: Legacy context API has been detected within a strict-mode tree.' + + '\n\nThe old API will be supported in all 16.x releases, but applications ' + + 'using it should migrate to the new version.' + + '\n\nPlease update the following components: ' + + 'FunctionalLegacyContextConsumer, LegacyContextConsumer, LegacyContextProvider' + + '\n\nLearn more about this warning here: ' + + 'https://fb.me/react-legacy-context' + + '\n in StrictMode (at **)' + + '\n in div (at **)' + + '\n in Root (at **)', + ); + + // Dedupe + ReactDOM.render(, container); + }); }); diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 7c95ba45e3b4b..b74aa2c30f65c 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -9,13 +9,8 @@ export const enableUserTimingAPI = __DEV__; -// Helps identify side effects in begin-phase lifecycle hooks and setState reducers: -export const debugRenderPhaseSideEffects = false; - -// In some cases, StrictMode should also double-render lifecycles. -// This can be confusing for tests though, -// And it can be bad for performance in production. -// This feature flag can be used to control the behavior: +// Helps identify side effects in render-phase lifecycle hooks and setState +// reducers by double invoking them in Strict Mode. export const debugRenderPhaseSideEffectsForStrictMode = __DEV__; // To preserve the "Pause on caught exceptions" behavior of the debugger, we diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 7f289919639e4..88f15f011553e 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -12,10 +12,8 @@ import invariant from 'shared/invariant'; import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags'; import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.native-fb'; -// Re-export dynamic flags from the fbsource version. -export const { - debugRenderPhaseSideEffects, -} = require('../shims/ReactFeatureFlags'); +// Uncomment to re-export dynamic flags from the fbsource version. +// export const {} = require('../shims/ReactFeatureFlags'); // The rest of the flags are static for better dead code elimination. export const enableUserTimingAPI = __DEV__; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 4a040b34b56d9..5c264ca4059a6 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -12,7 +12,6 @@ import invariant from 'shared/invariant'; import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags'; import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.native-oss'; -export const debugRenderPhaseSideEffects = false; export const debugRenderPhaseSideEffectsForStrictMode = false; export const enableUserTimingAPI = __DEV__; export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__; diff --git a/packages/shared/forks/ReactFeatureFlags.persistent.js b/packages/shared/forks/ReactFeatureFlags.persistent.js index 8f594d2c8b5c3..55f62f3390067 100644 --- a/packages/shared/forks/ReactFeatureFlags.persistent.js +++ b/packages/shared/forks/ReactFeatureFlags.persistent.js @@ -12,7 +12,6 @@ import invariant from 'shared/invariant'; import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags'; import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persistent'; -export const debugRenderPhaseSideEffects = false; export const debugRenderPhaseSideEffectsForStrictMode = false; export const enableUserTimingAPI = __DEV__; export const warnAboutDeprecatedLifecycles = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index e8d9b6ed3486d..bf83c976aacec 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -12,7 +12,6 @@ import invariant from 'shared/invariant'; import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags'; import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persistent'; -export const debugRenderPhaseSideEffects = false; export const debugRenderPhaseSideEffectsForStrictMode = false; export const enableUserTimingAPI = __DEV__; export const warnAboutDeprecatedLifecycles = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index bfe467843cff7..930a2077d82ec 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -12,7 +12,6 @@ import invariant from 'shared/invariant'; import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags'; import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persistent'; -export const debugRenderPhaseSideEffects = false; export const debugRenderPhaseSideEffectsForStrictMode = false; export const enableUserTimingAPI = __DEV__; export const warnAboutDeprecatedLifecycles = true; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index 44710dac054d4..b672259c200b6 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -12,7 +12,6 @@ import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.www'; // Re-export dynamic flags from the www version. export const { - debugRenderPhaseSideEffects, debugRenderPhaseSideEffectsForStrictMode, disableInputAttributeSyncing, enableTrustedTypesIntegration,