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

Use the disableLegacyMode where ever we check the ConcurrentMode mode #28657

Merged
merged 6 commits into from
Apr 3, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/react-native-renderer/src/ReactFabric.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {getPublicInstanceFromInternalInstanceHandle} from './ReactFiberConfigFab

// Module provided by RN:
import {ReactFiberErrorDialog} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
import {disableLegacyMode} from 'shared/ReactFeatureFlags';

if (typeof ReactFiberErrorDialog.showErrorDialog !== 'function') {
throw new Error(
Expand Down Expand Up @@ -106,6 +107,10 @@ function render(
callback: ?() => void,
concurrentRoot: ?boolean,
): ?ElementRef<ElementType> {
if (disableLegacyMode && !concurrentRoot) {
throw new Error('render: Unsupported Legacy Mode API.');
}

let root = roots.get(containerTag);

if (!root) {
Expand Down
6 changes: 6 additions & 0 deletions packages/react-native-renderer/src/ReactNativeRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ import {
isChildPublicInstance,
} from './ReactNativePublicCompat';

import {disableLegacyMode} from 'shared/ReactFeatureFlags';

// Module provided by RN:
import {ReactFiberErrorDialog} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';

Expand Down Expand Up @@ -109,6 +111,10 @@ function render(
containerTag: number,
callback: ?() => void,
): ?ElementRef<ElementType> {
if (disableLegacyMode) {
throw new Error('render: Unsupported Legacy Mode API.');
}

let root = roots.get(containerTag);

if (!root) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ describe('ReactNativeError', () => {
);
});

// @gate !disableLegacyMode
it('should be able to extract a component stack from a native view', () => {
const View = createReactNativeComponentClass('View', () => ({
validAttributes: {foo: true},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ beforeEach(() => {
.ReactNativeViewConfigRegistry.register;
});

// @gate !disableLegacyMode
it('fails to register the same event name with different types', async () => {
const InvalidEvents = createReactNativeComponentClass('InvalidEvents', () => {
if (!__DEV__) {
Expand Down Expand Up @@ -122,14 +123,18 @@ it('fails to register the same event name with different types', async () => {
).rejects.toThrow('Event cannot be both direct and bubbling: topChange');
});

// @gate !disableLegacyMode
it('fails if unknown/unsupported event types are dispatched', () => {
expect(RCTEventEmitter.register).toHaveBeenCalledTimes(1);
const EventEmitter = RCTEventEmitter.register.mock.calls[0][0];
const View = fakeRequireNativeComponent('View', {});

ReactNative.render(<View onUnspecifiedEvent={() => {}} />, 1);

expect(UIManager.__dumpHierarchyForJestTestsOnly()).toMatchSnapshot();
expect(UIManager.__dumpHierarchyForJestTestsOnly()).toMatchInlineSnapshot(`
"<native root> {}
View null"
`);
expect(UIManager.createView).toHaveBeenCalledTimes(1);

const target = UIManager.createView.mock.calls[0][0];
Expand All @@ -143,6 +148,7 @@ it('fails if unknown/unsupported event types are dispatched', () => {
}).toThrow('Unsupported top level event type "unspecifiedEvent" dispatched');
});

// @gate !disableLegacyMode
it('handles events', () => {
expect(RCTEventEmitter.register).toHaveBeenCalledTimes(1);
const EventEmitter = RCTEventEmitter.register.mock.calls[0][0];
Expand All @@ -167,7 +173,11 @@ it('handles events', () => {
1,
);

expect(UIManager.__dumpHierarchyForJestTestsOnly()).toMatchSnapshot();
expect(UIManager.__dumpHierarchyForJestTestsOnly()).toMatchInlineSnapshot(`
"<native root> {}
View {"foo":"outer"}
View {"foo":"inner"}"
`);
expect(UIManager.createView).toHaveBeenCalledTimes(2);

// Don't depend on the order of createView() calls.
Expand Down Expand Up @@ -200,6 +210,7 @@ it('handles events', () => {
});

// @gate !disableLegacyContext || !__DEV__
// @gate !disableLegacyMode
it('handles events on text nodes', () => {
expect(RCTEventEmitter.register).toHaveBeenCalledTimes(1);
const EventEmitter = RCTEventEmitter.register.mock.calls[0][0];
Expand Down Expand Up @@ -283,6 +294,7 @@ it('handles events on text nodes', () => {
]);
});

// @gate !disableLegacyMode
it('handles when a responder is unmounted while a touch sequence is in progress', () => {
const EventEmitter = RCTEventEmitter.register.mock.calls[0][0];
const View = fakeRequireNativeComponent('View', {id: true});
Expand Down Expand Up @@ -372,6 +384,7 @@ it('handles when a responder is unmounted while a touch sequence is in progress'
expect(log).toEqual(['two responder start']);
});

// @gate !disableLegacyMode
it('handles events without target', () => {
const EventEmitter = RCTEventEmitter.register.mock.calls[0][0];

Expand Down Expand Up @@ -462,6 +475,7 @@ it('handles events without target', () => {
]);
});

// @gate !disableLegacyMode
it('dispatches event with target as instance', () => {
const EventEmitter = RCTEventEmitter.register.mock.calls[0][0];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ describe('ReactNative', () => {
require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface').TextInputState;
});

// @gate !disableLegacyMode
it('should be able to create and render a native component', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand All @@ -58,6 +59,7 @@ describe('ReactNative', () => {
expect(UIManager.updateView).not.toBeCalled();
});

// @gate !disableLegacyMode
it('should be able to create and update a native component', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand All @@ -79,6 +81,7 @@ describe('ReactNative', () => {
expect(UIManager.updateView).toBeCalledWith(3, 'RCTView', {foo: 'bar'});
});

// @gate !disableLegacyMode
it('should not call UIManager.updateView after render for properties that have not changed', () => {
const Text = createReactNativeComponentClass('RCTText', () => ({
validAttributes: {foo: true},
Expand All @@ -105,6 +108,7 @@ describe('ReactNative', () => {
expect(UIManager.updateView).toHaveBeenCalledTimes(4);
});

// @gate !disableLegacyMode
it('should call dispatchCommand for native refs', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand Down Expand Up @@ -133,6 +137,7 @@ describe('ReactNative', () => {
);
});

// @gate !disableLegacyMode
it('should warn and no-op if calling dispatchCommand on non native refs', () => {
class BasicClass extends React.Component {
render() {
Expand Down Expand Up @@ -162,6 +167,7 @@ describe('ReactNative', () => {
expect(UIManager.dispatchViewManagerCommand).not.toBeCalled();
});

// @gate !disableLegacyMode
it('should call sendAccessibilityEvent for native refs', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand Down Expand Up @@ -192,6 +198,7 @@ describe('ReactNative', () => {
).toHaveBeenCalledWith(expect.any(Number), 'focus');
});

// @gate !disableLegacyMode
it('should warn and no-op if calling sendAccessibilityEvent on non native refs', () => {
class BasicClass extends React.Component {
render() {
Expand Down Expand Up @@ -221,6 +228,7 @@ describe('ReactNative', () => {
expect(UIManager.sendAccessibilityEvent).not.toBeCalled();
});

// @gate !disableLegacyMode
it('should not call UIManager.updateView from ref.setNativeProps for properties that have not changed', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand Down Expand Up @@ -254,6 +262,7 @@ describe('ReactNative', () => {
);
});

// @gate !disableLegacyMode
it('should call UIManager.measure on ref.measure', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand All @@ -280,6 +289,7 @@ describe('ReactNative', () => {
expect(successCallback).toHaveBeenCalledWith(10, 10, 100, 100, 0, 0);
});

// @gate !disableLegacyMode
it('should call UIManager.measureInWindow on ref.measureInWindow', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand All @@ -306,6 +316,7 @@ describe('ReactNative', () => {
expect(successCallback).toHaveBeenCalledWith(10, 10, 100, 100);
});

// @gate !disableLegacyMode
it('should support reactTag in ref.measureLayout', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand Down Expand Up @@ -346,6 +357,7 @@ describe('ReactNative', () => {
expect(successCallback).toHaveBeenCalledWith(1, 1, 100, 100);
});

// @gate !disableLegacyMode
it('should support ref in ref.measureLayout of host components', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand Down Expand Up @@ -382,6 +394,7 @@ describe('ReactNative', () => {
expect(successCallback).toHaveBeenCalledWith(1, 1, 100, 100);
});

// @gate !disableLegacyMode
it('returns the correct instance and calls it in the callback', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand All @@ -403,6 +416,7 @@ describe('ReactNative', () => {
expect(a).toBe(c);
});

// @gate !disableLegacyMode
it('renders and reorders children', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {title: true},
Expand All @@ -427,12 +441,59 @@ describe('ReactNative', () => {
const after = 'mxhpgwfralkeoivcstzy';

ReactNative.render(<Component chars={before} />, 11);
expect(UIManager.__dumpHierarchyForJestTestsOnly()).toMatchSnapshot();
expect(UIManager.__dumpHierarchyForJestTestsOnly()).toMatchInlineSnapshot(`
"<native root> {}
RCTView null
RCTView {"title":"a"}
RCTView {"title":"b"}
RCTView {"title":"c"}
RCTView {"title":"d"}
RCTView {"title":"e"}
RCTView {"title":"f"}
RCTView {"title":"g"}
RCTView {"title":"h"}
RCTView {"title":"i"}
RCTView {"title":"j"}
RCTView {"title":"k"}
RCTView {"title":"l"}
RCTView {"title":"m"}
RCTView {"title":"n"}
RCTView {"title":"o"}
RCTView {"title":"p"}
RCTView {"title":"q"}
RCTView {"title":"r"}
RCTView {"title":"s"}
RCTView {"title":"t"}"
`);

ReactNative.render(<Component chars={after} />, 11);
expect(UIManager.__dumpHierarchyForJestTestsOnly()).toMatchSnapshot();
expect(UIManager.__dumpHierarchyForJestTestsOnly()).toMatchInlineSnapshot(`
"<native root> {}
RCTView null
RCTView {"title":"m"}
RCTView {"title":"x"}
RCTView {"title":"h"}
RCTView {"title":"p"}
RCTView {"title":"g"}
RCTView {"title":"w"}
RCTView {"title":"f"}
RCTView {"title":"r"}
RCTView {"title":"a"}
RCTView {"title":"l"}
RCTView {"title":"k"}
RCTView {"title":"e"}
RCTView {"title":"o"}
RCTView {"title":"i"}
RCTView {"title":"v"}
RCTView {"title":"c"}
RCTView {"title":"s"}
RCTView {"title":"t"}
RCTView {"title":"z"}
RCTView {"title":"y"}"
`);
});

// @gate !disableLegacyMode
it('calls setState with no arguments', () => {
let mockArgs;
class Component extends React.Component {
Expand All @@ -448,6 +509,7 @@ describe('ReactNative', () => {
expect(mockArgs.length).toEqual(0);
});

// @gate !disableLegacyMode
it('should not throw when <View> is used inside of a <Text> ancestor', () => {
const Image = createReactNativeComponentClass('RCTImage', () => ({
validAttributes: {},
Expand Down Expand Up @@ -478,6 +540,7 @@ describe('ReactNative', () => {
);
});

// @gate !disableLegacyMode
it('should throw for text not inside of a <Text> ancestor', async () => {
const ScrollView = createReactNativeComponentClass('RCTScrollView', () => ({
validAttributes: {},
Expand Down Expand Up @@ -512,6 +575,7 @@ describe('ReactNative', () => {
);
});

// @gate !disableLegacyMode
it('should not throw for text inside of an indirect <Text> ancestor', () => {
const Text = createReactNativeComponentClass('RCTText', () => ({
validAttributes: {},
Expand All @@ -528,6 +592,7 @@ describe('ReactNative', () => {
);
});

// @gate !disableLegacyMode
it('findHostInstance_DEPRECATED should warn if used to find a host component inside StrictMode', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand Down Expand Up @@ -564,6 +629,7 @@ describe('ReactNative', () => {
expect(match).toBe(child);
});

// @gate !disableLegacyMode
it('findHostInstance_DEPRECATED should warn if passed a component that is inside StrictMode', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand Down Expand Up @@ -601,6 +667,7 @@ describe('ReactNative', () => {
expect(match).toBe(child);
});

// @gate !disableLegacyMode
it('findNodeHandle should warn if used to find a host component inside StrictMode', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand Down Expand Up @@ -635,6 +702,7 @@ describe('ReactNative', () => {
expect(match).toBe(child._nativeTag);
});

// @gate !disableLegacyMode
it('findNodeHandle should warn if passed a component that is inside StrictMode', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand Down Expand Up @@ -670,6 +738,7 @@ describe('ReactNative', () => {
expect(match).toBe(child._nativeTag);
});

// @gate !disableLegacyMode
it('blur on host component calls TextInputState', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand All @@ -687,6 +756,7 @@ describe('ReactNative', () => {
expect(TextInputState.blurTextInput).toHaveBeenCalledWith(viewRef.current);
});

// @gate !disableLegacyMode
it('focus on host component calls TextInputState', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand Down

This file was deleted.

Loading