mirror of
https://github.com/zoriya/react-native-web.git
synced 2025-12-06 06:36:13 +00:00
[change] React 18 support
* Support React 18 concurrency and constraints. * Add new render / hydrate functions. * Remove uses of findNodeHandle. * Expose ability to unmount an application once ran. Fix #1529 Close #2330
This commit is contained in:
committed by
Nicolas Gallagher
parent
3a024ee308
commit
9868738604
@@ -2,7 +2,7 @@
|
||||
"settings": {
|
||||
"react": {
|
||||
"pragma": "React",
|
||||
"version": "17.0",
|
||||
"version": "18.0",
|
||||
"flowVersion": "0.148.0" // Flow version
|
||||
}
|
||||
},
|
||||
|
||||
16800
package-lock.json
generated
16800
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -34,7 +34,7 @@
|
||||
"@babel/preset-env": "^7.18.6",
|
||||
"@babel/preset-flow": "^7.18.6",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@testing-library/react": "^12.1.5",
|
||||
"@testing-library/react": "^13.3.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-jest": "^28.1.2",
|
||||
"babel-plugin-add-module-exports": "^1.0.4",
|
||||
|
||||
@@ -71,4 +71,7 @@ const tests = {
|
||||
}))
|
||||
};
|
||||
|
||||
ReactDOM.render(<App tests={tests} />, document.querySelector('.root'));
|
||||
const root = document.querySelector('.root');
|
||||
const element = <App tests={tests} />;
|
||||
|
||||
ReactDOM.createRoot(root).render(element);
|
||||
|
||||
@@ -69,6 +69,10 @@ If the client should hydrate server-rendered HTML.
|
||||
The initial props passed to the root component.
|
||||
{% endcall %}
|
||||
|
||||
{% call macro.prop('mode', '"concurrent" | "legacy"') %}
|
||||
Default is 'concurrent'. Setting to 'legacy' will make the app will behave as if it’s running React 17.
|
||||
{% endcall %}
|
||||
|
||||
{% call macro.prop('rootTag', 'HTMLElement') %}
|
||||
The native element into which the application is rendered.
|
||||
{% endcall %}
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
"dependencies": {
|
||||
"babel-plugin-react-native-web": "0.18.12",
|
||||
"next": "^12.2.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"react-native-web": "0.18.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -25,18 +25,18 @@ export default function AppStatePage() {
|
||||
const iframeRootTag = document.createElement('div');
|
||||
iframeRootTag.id = 'iframe-root';
|
||||
iframeBody.appendChild(iframeRootTag);
|
||||
AppRegistry.runApplication('App', { rootTag: iframeRootTag });
|
||||
const app1 = AppRegistry.runApplication('App', { rootTag: iframeRootTag });
|
||||
|
||||
const shadowElement = shadowRef.current;
|
||||
const shadowRoot = shadowElement.attachShadow({ mode: 'open' });
|
||||
const shadowRootTag = document.createElement('div');
|
||||
shadowRootTag.id = 'shadow-root';
|
||||
shadowRoot.appendChild(shadowRootTag);
|
||||
AppRegistry.runApplication('App', { rootTag: shadowRootTag });
|
||||
const app2 = AppRegistry.runApplication('App', { rootTag: shadowRootTag });
|
||||
|
||||
return () => {
|
||||
AppRegistry.unmountApplicationComponentAtRootTag(iframeRootTag);
|
||||
AppRegistry.unmountApplicationComponentAtRootTag(shadowRootTag);
|
||||
app1.unmount();
|
||||
app2.unmount();
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
"styleq": "^0.1.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^17.0.2 || ^18.0.0",
|
||||
"react-dom": "^17.0.2 || ^18.0.0"
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
},
|
||||
"author": "Nicolas Gallagher",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -7,9 +7,8 @@
|
||||
|
||||
import ActivityIndicator from '..';
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { createEventTarget } from 'dom-event-testing-library';
|
||||
import { render } from '@testing-library/react';
|
||||
import { act, render } from '@testing-library/react';
|
||||
|
||||
describe('components/ActivityIndicator', () => {
|
||||
describe('prop "accessibilityLabel"', () => {
|
||||
|
||||
@@ -21,30 +21,40 @@ type Props = {
|
||||
|
||||
const RootTagContext: React.Context<any> = React.createContext(null);
|
||||
|
||||
export default function AppContainer(props: Props): React.Node {
|
||||
const { children, WrapperComponent } = props;
|
||||
const AppContainer: React.AbstractComponent<Props> = React.forwardRef(
|
||||
(props: Props, forwardedRef?: React.Ref<any>) => {
|
||||
const { children, WrapperComponent } = props;
|
||||
|
||||
let innerView = (
|
||||
<View
|
||||
children={children}
|
||||
key={1}
|
||||
pointerEvents="box-none"
|
||||
style={styles.appContainer}
|
||||
/>
|
||||
);
|
||||
let innerView = (
|
||||
<View
|
||||
children={children}
|
||||
key={1}
|
||||
pointerEvents="box-none"
|
||||
style={styles.appContainer}
|
||||
/>
|
||||
);
|
||||
|
||||
if (WrapperComponent) {
|
||||
innerView = <WrapperComponent>{innerView}</WrapperComponent>;
|
||||
if (WrapperComponent) {
|
||||
innerView = <WrapperComponent>{innerView}</WrapperComponent>;
|
||||
}
|
||||
|
||||
return (
|
||||
<RootTagContext.Provider value={props.rootTag}>
|
||||
<View
|
||||
pointerEvents="box-none"
|
||||
ref={forwardedRef}
|
||||
style={styles.appContainer}
|
||||
>
|
||||
{innerView}
|
||||
</View>
|
||||
</RootTagContext.Provider>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<RootTagContext.Provider value={props.rootTag}>
|
||||
<View pointerEvents="box-none" style={styles.appContainer}>
|
||||
{innerView}
|
||||
</View>
|
||||
</RootTagContext.Provider>
|
||||
);
|
||||
}
|
||||
AppContainer.displayName = 'AppContainer';
|
||||
|
||||
export default AppContainer;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
appContainer: {
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
|
||||
import AppRegistry from '..';
|
||||
import React from 'react';
|
||||
|
||||
import { act } from '@testing-library/react';
|
||||
const NoopComponent = () => React.createElement('div');
|
||||
|
||||
describe('AppRegistry', () => {
|
||||
describe.each([['concurrent'], ['legacy']])('AppRegistry', (mode) => {
|
||||
describe('runApplication', () => {
|
||||
let rootTag;
|
||||
|
||||
@@ -27,18 +27,52 @@ describe('AppRegistry', () => {
|
||||
test('callback after render', () => {
|
||||
const callback = jest.fn();
|
||||
AppRegistry.registerComponent('App', () => NoopComponent);
|
||||
AppRegistry.runApplication('App', {
|
||||
initialProps: {},
|
||||
rootTag,
|
||||
callback
|
||||
act(() => {
|
||||
AppRegistry.runApplication('App', {
|
||||
initialProps: {},
|
||||
rootTag,
|
||||
callback,
|
||||
mode
|
||||
});
|
||||
});
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('unmount ran application', () => {
|
||||
const setMountedState = jest.fn();
|
||||
const MountedStateComponent = () => {
|
||||
React.useEffect(() => {
|
||||
setMountedState(true);
|
||||
return () => {
|
||||
setMountedState(false);
|
||||
};
|
||||
}, []);
|
||||
return <NoopComponent />;
|
||||
};
|
||||
|
||||
AppRegistry.registerComponent('App', () => MountedStateComponent);
|
||||
let application;
|
||||
act(() => {
|
||||
application = AppRegistry.runApplication('App', {
|
||||
initialProps: {},
|
||||
rootTag,
|
||||
mode
|
||||
});
|
||||
});
|
||||
expect(setMountedState).toHaveBeenCalledTimes(1);
|
||||
expect(setMountedState).toHaveBeenLastCalledWith(true);
|
||||
act(() => {
|
||||
application.unmount();
|
||||
});
|
||||
expect(setMountedState).toHaveBeenCalledTimes(2);
|
||||
expect(setMountedState).toHaveBeenLastCalledWith(false);
|
||||
});
|
||||
|
||||
test('styles roots in different documents', () => {
|
||||
AppRegistry.registerComponent('App', () => NoopComponent);
|
||||
AppRegistry.runApplication('App', { initialProps: {}, rootTag });
|
||||
|
||||
act(() => {
|
||||
AppRegistry.runApplication('App', { initialProps: {}, rootTag, mode });
|
||||
});
|
||||
// Create iframe context
|
||||
const iframe = document.createElement('iframe');
|
||||
document.body.appendChild(iframe);
|
||||
@@ -49,9 +83,12 @@ describe('AppRegistry', () => {
|
||||
|
||||
// Run in iframe
|
||||
AppRegistry.registerComponent('App', () => NoopComponent);
|
||||
AppRegistry.runApplication('App', {
|
||||
initialProps: {},
|
||||
rootTag: iframeRootTag
|
||||
act(() => {
|
||||
AppRegistry.runApplication('App', {
|
||||
initialProps: {},
|
||||
rootTag: iframeRootTag,
|
||||
mode
|
||||
});
|
||||
});
|
||||
|
||||
const iframedoc = iframeRootTag.ownerDocument;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type { Application } from './renderApplication';
|
||||
import type { ComponentType, Node } from 'react';
|
||||
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
@@ -75,7 +76,7 @@ export default class AppRegistry {
|
||||
appParameters ? appParameters.initialProps : emptyObject,
|
||||
wrapperComponentProvider && wrapperComponentProvider(appParameters)
|
||||
),
|
||||
run: (appParameters) =>
|
||||
run: (appParameters): Application =>
|
||||
renderApplication(
|
||||
componentProviderInstrumentationHook(componentProvider),
|
||||
wrapperComponentProvider && wrapperComponentProvider(appParameters),
|
||||
@@ -83,6 +84,7 @@ export default class AppRegistry {
|
||||
{
|
||||
hydrate: appParameters.hydrate || false,
|
||||
initialProps: appParameters.initialProps || emptyObject,
|
||||
mode: appParameters.mode || 'concurrent',
|
||||
rootTag: appParameters.rootTag
|
||||
}
|
||||
)
|
||||
@@ -107,7 +109,7 @@ export default class AppRegistry {
|
||||
return appKey;
|
||||
}
|
||||
|
||||
static runApplication(appKey: string, appParameters: Object): void {
|
||||
static runApplication(appKey: string, appParameters: Object): Application {
|
||||
const isDevelopment =
|
||||
process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test';
|
||||
if (isDevelopment) {
|
||||
@@ -128,7 +130,7 @@ export default class AppRegistry {
|
||||
'This is either due to an import error during initialization or failure to call AppRegistry.registerComponent.'
|
||||
);
|
||||
|
||||
runnables[appKey].run(appParameters);
|
||||
return runnables[appKey].run(appParameters);
|
||||
}
|
||||
|
||||
static setComponentProviderInstrumentationHook(
|
||||
|
||||
@@ -12,10 +12,14 @@ import type { ComponentType, Node } from 'react';
|
||||
|
||||
import AppContainer from './AppContainer';
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
import render, { hydrate } from '../render';
|
||||
import renderLegacy, { hydrateLegacy, render, hydrate } from '../render';
|
||||
import StyleSheet from '../StyleSheet';
|
||||
import React from 'react';
|
||||
|
||||
export type Application = {
|
||||
unmount: () => void
|
||||
};
|
||||
|
||||
export default function renderApplication<Props: Object>(
|
||||
RootComponent: ComponentType<Props>,
|
||||
WrapperComponent?: ?ComponentType<*>,
|
||||
@@ -23,20 +27,30 @@ export default function renderApplication<Props: Object>(
|
||||
options: {
|
||||
hydrate: boolean,
|
||||
initialProps: Props,
|
||||
mode: 'concurrent' | 'legacy',
|
||||
rootTag: any
|
||||
}
|
||||
) {
|
||||
const { hydrate: shouldHydrate, initialProps, rootTag } = options;
|
||||
const renderFn = shouldHydrate ? hydrate : render;
|
||||
): Application {
|
||||
const { hydrate: shouldHydrate, initialProps, mode, rootTag } = options;
|
||||
const renderFn = shouldHydrate
|
||||
? mode === 'concurrent'
|
||||
? hydrate
|
||||
: hydrateLegacy
|
||||
: mode === 'concurrent'
|
||||
? render
|
||||
: renderLegacy;
|
||||
|
||||
invariant(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag);
|
||||
|
||||
renderFn(
|
||||
<AppContainer WrapperComponent={WrapperComponent} rootTag={rootTag}>
|
||||
return renderFn(
|
||||
<AppContainer
|
||||
WrapperComponent={WrapperComponent}
|
||||
ref={callback}
|
||||
rootTag={rootTag}
|
||||
>
|
||||
<RootComponent {...initialProps} />
|
||||
</AppContainer>,
|
||||
rootTag,
|
||||
callback
|
||||
rootTag
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import Button from '..';
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { createEventTarget } from 'dom-event-testing-library';
|
||||
import { render } from '@testing-library/react';
|
||||
import { act, render } from '@testing-library/react';
|
||||
|
||||
describe('components/Button', () => {
|
||||
test('prop "accessibilityLabel"', () => {
|
||||
|
||||
@@ -7,9 +7,8 @@
|
||||
|
||||
import CheckBox from '../';
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { createEventTarget } from 'dom-event-testing-library';
|
||||
import { render } from '@testing-library/react';
|
||||
import { act, render } from '@testing-library/react';
|
||||
|
||||
function findCheckbox(container) {
|
||||
return container.firstChild.querySelector('input');
|
||||
|
||||
@@ -7,13 +7,12 @@
|
||||
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import * as AssetRegistry from '../../../modules/AssetRegistry';
|
||||
import Image from '../';
|
||||
import ImageLoader, { ImageUriCache } from '../../../modules/ImageLoader';
|
||||
import PixelRatio from '../../PixelRatio';
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { act, render } from '@testing-library/react';
|
||||
|
||||
const originalImage = window.Image;
|
||||
|
||||
|
||||
@@ -7,9 +7,8 @@
|
||||
|
||||
import React from 'react';
|
||||
import Pressable from '../';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { createEventTarget } from 'dom-event-testing-library';
|
||||
import { render } from '@testing-library/react';
|
||||
import { act, render } from '@testing-library/react';
|
||||
|
||||
describe('components/Pressable', () => {
|
||||
test('default', () => {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import React from 'react';
|
||||
import ScrollView from '../';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { createEventTarget } from 'dom-event-testing-library';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import { render } from '@testing-library/react';
|
||||
import { act, render } from '@testing-library/react';
|
||||
|
||||
describe('components/ScrollView', () => {
|
||||
describe('prop "centerContent"', () => {
|
||||
|
||||
@@ -9,9 +9,8 @@
|
||||
|
||||
import React from 'react';
|
||||
import Text from '../';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { createEventTarget } from 'dom-event-testing-library';
|
||||
import { render } from '@testing-library/react';
|
||||
import { act, render } from '@testing-library/react';
|
||||
|
||||
describe('components/Text', () => {
|
||||
test('default', () => {
|
||||
|
||||
@@ -7,9 +7,8 @@
|
||||
|
||||
import React from 'react';
|
||||
import TextInput from '..';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { createEventTarget } from 'dom-event-testing-library';
|
||||
import { render } from '@testing-library/react';
|
||||
import { act, render } from '@testing-library/react';
|
||||
|
||||
function findInput(container) {
|
||||
return container.querySelector('input');
|
||||
|
||||
@@ -13,7 +13,6 @@ import type { Node } from 'React';
|
||||
|
||||
import AccessibilityUtil from '../../modules/AccessibilityUtil';
|
||||
import BoundingDimensions from './BoundingDimensions';
|
||||
import findNodeHandle from '../findNodeHandle';
|
||||
import normalizeColor from 'normalize-css-color';
|
||||
import Position from './Position';
|
||||
import React from 'react';
|
||||
@@ -73,6 +72,11 @@ const extractSingleTouch = (nativeEvent) => {
|
||||
* return merge(this.touchableGetInitialState(), yourComponentState);
|
||||
* }
|
||||
*
|
||||
* - Add a method to get your touchable component's node.
|
||||
* getTouchableNode: function() {
|
||||
* return this.touchableRef.current
|
||||
* }
|
||||
*
|
||||
* - Choose the rendered component who's touches should start the interactive
|
||||
* sequence. On that rendered node, forward all `Touchable` responder
|
||||
* handlers. You can choose any rendered node you like. Choose a node whose
|
||||
@@ -81,6 +85,7 @@ const extractSingleTouch = (nativeEvent) => {
|
||||
* // In render function:
|
||||
* return (
|
||||
* <View
|
||||
* ref={this.touchableRef}
|
||||
* onStartShouldSetResponder={this.touchableHandleStartShouldSetResponder}
|
||||
* onResponderTerminationRequest={this.touchableHandleResponderTerminationRequest}
|
||||
* onResponderGrant={this.touchableHandleResponderGrant}
|
||||
@@ -366,8 +371,8 @@ const LONG_PRESS_ALLOWED_MOVEMENT = 10;
|
||||
const TouchableMixin = {
|
||||
// HACK (part 1): basic support for touchable interactions using a keyboard
|
||||
componentDidMount: function () {
|
||||
this._touchableNode = findNodeHandle(this);
|
||||
if (this._touchableNode && this._touchableNode.addEventListener) {
|
||||
const touchableNode = this.getTouchableNode && this.getTouchableNode();
|
||||
if (touchableNode && touchableNode.addEventListener) {
|
||||
this._touchableBlurListener = (e) => {
|
||||
if (this._isTouchableKeyboardActive) {
|
||||
if (
|
||||
@@ -379,7 +384,7 @@ const TouchableMixin = {
|
||||
this._isTouchableKeyboardActive = false;
|
||||
}
|
||||
};
|
||||
this._touchableNode.addEventListener('blur', this._touchableBlurListener);
|
||||
touchableNode.addEventListener('blur', this._touchableBlurListener);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -387,11 +392,9 @@ const TouchableMixin = {
|
||||
* Clear all timeouts on unmount
|
||||
*/
|
||||
componentWillUnmount: function () {
|
||||
if (this._touchableNode && this._touchableNode.addEventListener) {
|
||||
this._touchableNode.removeEventListener(
|
||||
'blur',
|
||||
this._touchableBlurListener
|
||||
);
|
||||
const touchableNode = this.getTouchableNode && this.getTouchableNode();
|
||||
if (touchableNode && touchableNode.addEventListener) {
|
||||
touchableNode.removeEventListener('blur', this._touchableBlurListener);
|
||||
}
|
||||
this.touchableDelayTimeout && clearTimeout(this.touchableDelayTimeout);
|
||||
this.longPressDelayTimeout && clearTimeout(this.longPressDelayTimeout);
|
||||
@@ -399,7 +402,6 @@ const TouchableMixin = {
|
||||
// Clear DOM nodes
|
||||
this.pressInLocation = null;
|
||||
this.state.touchable.responderID = null;
|
||||
this._touchableNode = null;
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,9 +8,8 @@
|
||||
import React from 'react';
|
||||
import View from '../';
|
||||
import StyleSheet from '../../StyleSheet';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { createEventTarget } from 'dom-event-testing-library';
|
||||
import { render } from '@testing-library/react';
|
||||
import { act, render } from '@testing-library/react';
|
||||
|
||||
describe('components/View', () => {
|
||||
test('default', () => {
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
|
||||
import { findDOMNode } from 'react-dom';
|
||||
|
||||
/**
|
||||
* @deprecated imperatively finding the DOM element of a react component has been deprecated in React 18.
|
||||
* You should use ref properties on the component instead.
|
||||
*/
|
||||
const findNodeHandle = (component) => {
|
||||
let node;
|
||||
|
||||
|
||||
@@ -7,15 +7,46 @@
|
||||
* @noflow
|
||||
*/
|
||||
|
||||
import { hydrate as domHydrate, render as domRender } from 'react-dom';
|
||||
import {
|
||||
hydrate as domLegacyHydrate,
|
||||
render as domLegacyRender
|
||||
} from 'react-dom';
|
||||
import {
|
||||
createRoot as domCreateRoot,
|
||||
hydrateRoot as domHydrateRoot
|
||||
} from 'react-dom/client';
|
||||
|
||||
import unmountComponentAtNode from '../unmountComponentAtNode';
|
||||
import { createSheet } from '../StyleSheet/dom';
|
||||
|
||||
export function hydrate(element, root, callback) {
|
||||
export function hydrate(element, root) {
|
||||
createSheet(root);
|
||||
return domHydrate(element, root, callback);
|
||||
return domHydrateRoot(root, element);
|
||||
}
|
||||
|
||||
export default function render(element, root, callback) {
|
||||
export function render(element, root) {
|
||||
createSheet(root);
|
||||
return domRender(element, root, callback);
|
||||
const reactRoot = domCreateRoot(root);
|
||||
reactRoot.render(element);
|
||||
return reactRoot;
|
||||
}
|
||||
|
||||
export function hydrateLegacy(element, root, callback) {
|
||||
createSheet(root);
|
||||
domLegacyHydrate(element, root, callback);
|
||||
return {
|
||||
unmount: function () {
|
||||
return unmountComponentAtNode(root);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default function renderLegacy(element, root, callback) {
|
||||
createSheet(root);
|
||||
domLegacyRender(element, root, callback);
|
||||
return {
|
||||
unmount: function () {
|
||||
return unmountComponentAtNode(root);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
*/
|
||||
|
||||
import Dimensions from '../../exports/Dimensions';
|
||||
import findNodeHandle from '../../exports/findNodeHandle';
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
import Platform from '../../exports/Platform';
|
||||
import TextInputState from '../TextInputState';
|
||||
@@ -347,17 +346,6 @@ const ScrollResponderMixin = {
|
||||
return isAnimating;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the node that represents native view that can be scrolled.
|
||||
* Components can pass what node to use by defining a `getScrollableNode`
|
||||
* function otherwise `this` is used.
|
||||
*/
|
||||
scrollResponderGetScrollableNode: function (): any {
|
||||
return this.getScrollableNode
|
||||
? this.getScrollableNode()
|
||||
: findNodeHandle(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* A helper function to scroll to a specific point in the scrollview.
|
||||
* This is currently used to help focus on child textviews, but can also
|
||||
@@ -381,7 +369,7 @@ const ScrollResponderMixin = {
|
||||
} else {
|
||||
({ x, y, animated } = x || emptyObject);
|
||||
}
|
||||
const node = this.scrollResponderGetScrollableNode();
|
||||
const node = this.getScrollableNode();
|
||||
const left = x || 0;
|
||||
const top = y || 0;
|
||||
if (typeof node.scroll === 'function') {
|
||||
@@ -437,7 +425,7 @@ const ScrollResponderMixin = {
|
||||
this.preventNegativeScrollOffset = !!preventNegativeScrollOffset;
|
||||
UIManager.measureLayout(
|
||||
nodeHandle,
|
||||
findNodeHandle(this.getInnerViewNode()),
|
||||
this.getInnerViewNode(),
|
||||
this.scrollResponderTextInputFocusError,
|
||||
this.scrollResponderInputMeasureAndScrollToKeyboard
|
||||
);
|
||||
|
||||
@@ -8,53 +8,11 @@
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import * as ReactDOMServer from 'react-dom/server';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { act, render } from '@testing-library/react';
|
||||
import { createEventTarget } from 'dom-event-testing-library';
|
||||
import createEventHandle from '..';
|
||||
|
||||
function createRoot(rootNode) {
|
||||
return {
|
||||
render(element) {
|
||||
ReactDOM.render(element, rootNode);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
describe('create-event-handle', () => {
|
||||
let root;
|
||||
let rootNode;
|
||||
|
||||
beforeEach(() => {
|
||||
rootNode = document.createElement('div');
|
||||
document.body.appendChild(rootNode);
|
||||
root = createRoot(rootNode);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
root.render(null);
|
||||
document.body.removeChild(rootNode);
|
||||
rootNode = null;
|
||||
root = null;
|
||||
});
|
||||
|
||||
test('can render correctly using ReactDOMServer', () => {
|
||||
const listener = jest.fn();
|
||||
const targetRef = React.createRef();
|
||||
const addClickListener = createEventHandle('click');
|
||||
|
||||
function Component() {
|
||||
React.useEffect(() => {
|
||||
return addClickListener(targetRef.current, listener);
|
||||
});
|
||||
return <div ref={targetRef} />;
|
||||
}
|
||||
|
||||
const output = ReactDOMServer.renderToString(<Component />);
|
||||
expect(output).toBe('<div data-reactroot=""></div>');
|
||||
});
|
||||
|
||||
describe('createEventTarget()', () => {
|
||||
test('event dispatched on target', () => {
|
||||
const listener = jest.fn();
|
||||
@@ -68,9 +26,7 @@ describe('create-event-handle', () => {
|
||||
return <div ref={targetRef} />;
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const target = createEventTarget(targetRef.current);
|
||||
|
||||
@@ -113,9 +69,7 @@ describe('create-event-handle', () => {
|
||||
);
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const parent = createEventTarget(parentRef.current);
|
||||
|
||||
@@ -164,9 +118,7 @@ describe('create-event-handle', () => {
|
||||
);
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const child = createEventTarget(childRef.current);
|
||||
|
||||
@@ -196,9 +148,7 @@ describe('create-event-handle', () => {
|
||||
);
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const text = createEventTarget(childRef.current.firstChild);
|
||||
|
||||
@@ -221,9 +171,8 @@ describe('create-event-handle', () => {
|
||||
return <div ref={targetRef} />;
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component target={document} />);
|
||||
});
|
||||
render(<Component target={document} />);
|
||||
|
||||
const target = createEventTarget(targetRef.current);
|
||||
act(() => {
|
||||
target.click();
|
||||
@@ -244,9 +193,8 @@ describe('create-event-handle', () => {
|
||||
return <div ref={targetRef} />;
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component target={window} />);
|
||||
});
|
||||
render(<Component target={window} />);
|
||||
|
||||
const target = createEventTarget(targetRef.current);
|
||||
act(() => {
|
||||
target.click();
|
||||
@@ -267,9 +215,7 @@ describe('create-event-handle', () => {
|
||||
return <div ref={targetRef} />;
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
act(() => {
|
||||
const event = new CustomEvent('magic-event', { bubbles: true });
|
||||
@@ -312,9 +258,7 @@ describe('create-event-handle', () => {
|
||||
);
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const child = createEventTarget(childRef.current);
|
||||
|
||||
@@ -371,9 +315,7 @@ describe('create-event-handle', () => {
|
||||
);
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const child = createEventTarget(childRef.current);
|
||||
|
||||
@@ -416,9 +358,7 @@ describe('create-event-handle', () => {
|
||||
);
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const child = createEventTarget(childRef.current);
|
||||
|
||||
@@ -447,9 +387,7 @@ describe('create-event-handle', () => {
|
||||
return <div ref={targetRef} />;
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const target = createEventTarget(targetRef.current);
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import * as ReactDOMServer from 'react-dom/server';
|
||||
import createEventHandle from '..';
|
||||
|
||||
describe('create-event-handle', () => {
|
||||
test('can render correctly using ReactDOMServer', () => {
|
||||
const listener = jest.fn();
|
||||
const targetRef = React.createRef();
|
||||
const addClickListener = createEventHandle('click');
|
||||
|
||||
function Component() {
|
||||
React.useEffect(() => {
|
||||
return addClickListener(targetRef.current, listener);
|
||||
});
|
||||
return <div ref={targetRef} />;
|
||||
}
|
||||
|
||||
const output = ReactDOMServer.renderToString(<Component />);
|
||||
expect(output).toBe('<div></div>');
|
||||
});
|
||||
});
|
||||
@@ -8,36 +8,11 @@
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { act, render } from '@testing-library/react';
|
||||
import { createEventTarget } from 'dom-event-testing-library';
|
||||
import useEvent from '..';
|
||||
|
||||
function createRoot(rootNode) {
|
||||
return {
|
||||
render(element) {
|
||||
ReactDOM.render(element, rootNode);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
describe('use-event', () => {
|
||||
let root;
|
||||
let rootNode;
|
||||
|
||||
beforeEach(() => {
|
||||
rootNode = document.createElement('div');
|
||||
document.body.appendChild(rootNode);
|
||||
root = createRoot(rootNode);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
root.render(null);
|
||||
document.body.removeChild(rootNode);
|
||||
rootNode = null;
|
||||
root = null;
|
||||
});
|
||||
|
||||
describe('setListener()', () => {
|
||||
test('event dispatched on target', () => {
|
||||
const listener = jest.fn();
|
||||
@@ -51,9 +26,7 @@ describe('use-event', () => {
|
||||
return <div ref={targetRef} />;
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const target = createEventTarget(targetRef.current);
|
||||
|
||||
@@ -85,9 +58,7 @@ describe('use-event', () => {
|
||||
);
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const parent = createEventTarget(parentRef.current);
|
||||
|
||||
@@ -125,9 +96,7 @@ describe('use-event', () => {
|
||||
);
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const child = createEventTarget(childRef.current);
|
||||
|
||||
@@ -157,9 +126,7 @@ describe('use-event', () => {
|
||||
);
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const text = createEventTarget(childRef.current.firstChild);
|
||||
|
||||
@@ -182,9 +149,8 @@ describe('use-event', () => {
|
||||
return <div ref={targetRef} />;
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component target={document} />);
|
||||
});
|
||||
render(<Component target={document} />);
|
||||
|
||||
const target = createEventTarget(targetRef.current);
|
||||
act(() => {
|
||||
target.click();
|
||||
@@ -205,9 +171,8 @@ describe('use-event', () => {
|
||||
return <div ref={targetRef} />;
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component target={window} />);
|
||||
});
|
||||
render(<Component target={window} />);
|
||||
|
||||
const target = createEventTarget(targetRef.current);
|
||||
act(() => {
|
||||
target.click();
|
||||
@@ -229,18 +194,16 @@ describe('use-event', () => {
|
||||
return <div ref={targetRef} />;
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component onClick={listener} />);
|
||||
});
|
||||
const { rerender } = render(<Component onClick={listener} />);
|
||||
|
||||
const target = createEventTarget(targetRef.current);
|
||||
act(() => {
|
||||
target.click();
|
||||
});
|
||||
expect(listener).toBeCalledTimes(1);
|
||||
act(() => {
|
||||
// this should replace the listener
|
||||
root.render(<Component onClick={listenerAlt} />);
|
||||
});
|
||||
|
||||
rerender(<Component onClick={listenerAlt} />);
|
||||
|
||||
act(() => {
|
||||
target.click();
|
||||
});
|
||||
@@ -260,18 +223,17 @@ describe('use-event', () => {
|
||||
return <div ref={targetRef} />;
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component off={false} />);
|
||||
});
|
||||
const { unmount } = render(<Component off={false} />);
|
||||
|
||||
const target = createEventTarget(targetRef.current);
|
||||
act(() => {
|
||||
target.click();
|
||||
});
|
||||
expect(listener).toBeCalledTimes(1);
|
||||
act(() => {
|
||||
// this should unset the listener
|
||||
root.render(<Component off={true} />);
|
||||
});
|
||||
|
||||
// this should unset the listener
|
||||
unmount();
|
||||
|
||||
listener.mockClear();
|
||||
act(() => {
|
||||
target.click();
|
||||
@@ -291,9 +253,7 @@ describe('use-event', () => {
|
||||
return <div ref={targetRef} />;
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
act(() => {
|
||||
const event = new CustomEvent('magic-event', { bubbles: true });
|
||||
@@ -335,9 +295,7 @@ describe('use-event', () => {
|
||||
);
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const child = createEventTarget(childRef.current);
|
||||
|
||||
@@ -391,9 +349,7 @@ describe('use-event', () => {
|
||||
);
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const child = createEventTarget(childRef.current);
|
||||
|
||||
@@ -425,10 +381,8 @@ describe('use-event', () => {
|
||||
return <div />;
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
root.render(null);
|
||||
});
|
||||
const { unmount } = render(<Component />);
|
||||
unmount();
|
||||
|
||||
const target = createEventTarget(document);
|
||||
|
||||
@@ -462,9 +416,7 @@ describe('use-event', () => {
|
||||
);
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const child = createEventTarget(childRef.current);
|
||||
|
||||
@@ -493,9 +445,7 @@ describe('use-event', () => {
|
||||
return <div ref={targetRef} />;
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const target = createEventTarget(targetRef.current);
|
||||
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { act, render } from '@testing-library/react';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import {
|
||||
describeWithPointerEvent,
|
||||
clearPointers,
|
||||
@@ -17,30 +16,12 @@ import {
|
||||
import useHover from '..';
|
||||
import { testOnly_resetActiveModality } from '../../modality';
|
||||
|
||||
function createRoot(rootNode) {
|
||||
return {
|
||||
render(element) {
|
||||
ReactDOM.render(element, rootNode);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
describeWithPointerEvent('useHover', (hasPointerEvents) => {
|
||||
let root;
|
||||
let rootNode;
|
||||
|
||||
beforeEach(() => {
|
||||
setPointerEvent(hasPointerEvents);
|
||||
rootNode = document.createElement('div');
|
||||
document.body.appendChild(rootNode);
|
||||
root = createRoot(rootNode);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
root.render(null);
|
||||
document.body.removeChild(rootNode);
|
||||
rootNode = null;
|
||||
root = null;
|
||||
testOnly_resetActiveModality();
|
||||
// make sure all tests reset state machine tracking pointers on the mock surface
|
||||
clearPointers();
|
||||
@@ -70,9 +51,7 @@ describeWithPointerEvent('useHover', (hasPointerEvents) => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
};
|
||||
|
||||
test('contains the hover gesture', () => {
|
||||
@@ -111,9 +90,7 @@ describeWithPointerEvent('useHover', (hasPointerEvents) => {
|
||||
});
|
||||
return <div ref={ref} />;
|
||||
};
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
};
|
||||
|
||||
test('does not call callbacks', () => {
|
||||
@@ -140,9 +117,7 @@ describeWithPointerEvent('useHover', (hasPointerEvents) => {
|
||||
useHover(ref, { onHoverStart });
|
||||
return <div ref={ref} />;
|
||||
};
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
};
|
||||
|
||||
test('is called for mouse pointers', () => {
|
||||
@@ -186,9 +161,7 @@ describeWithPointerEvent('useHover', (hasPointerEvents) => {
|
||||
useHover(ref, { onHoverChange });
|
||||
return <div ref={ref} />;
|
||||
};
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
};
|
||||
|
||||
test('is called for mouse pointers', () => {
|
||||
@@ -232,9 +205,7 @@ describeWithPointerEvent('useHover', (hasPointerEvents) => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
};
|
||||
|
||||
test('is called for mouse pointers', () => {
|
||||
@@ -278,9 +249,7 @@ describeWithPointerEvent('useHover', (hasPointerEvents) => {
|
||||
useHover(ref, { onHoverUpdate });
|
||||
return <div ref={ref} />;
|
||||
};
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
|
||||
const target = createEventTarget(ref.current);
|
||||
act(() => {
|
||||
@@ -310,9 +279,7 @@ describeWithPointerEvent('useHover', (hasPointerEvents) => {
|
||||
});
|
||||
return <div ref={ref} />;
|
||||
};
|
||||
act(() => {
|
||||
root.render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
};
|
||||
|
||||
test('callbacks are called each time', () => {
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { cleanup, render } from '@testing-library/react';
|
||||
import { act, render } from '@testing-library/react';
|
||||
import useMergeRefs from '..';
|
||||
|
||||
describe('modules/useMergeRefs', () => {
|
||||
@@ -16,8 +15,6 @@ describe('modules/useMergeRefs', () => {
|
||||
return <div ref={mergedRef} {...rest} />;
|
||||
}
|
||||
|
||||
afterEach(cleanup);
|
||||
|
||||
test('handles no refs', () => {
|
||||
act(() => {
|
||||
render(<TestComponent refs={[]} />);
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { act, render } from '@testing-library/react';
|
||||
import React, { createRef } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import useResponderEvents from '..';
|
||||
import { getResponderNode, terminateResponder } from '../ResponderSystem';
|
||||
import {
|
||||
@@ -19,21 +18,7 @@ import {
|
||||
} from 'dom-event-testing-library';
|
||||
|
||||
describe('useResponderEvents', () => {
|
||||
let container;
|
||||
|
||||
function render(element) {
|
||||
ReactDOM.render(element, container);
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
render(null);
|
||||
document.body.removeChild(container);
|
||||
container = null;
|
||||
// make sure all tests end with the current responder being reset
|
||||
terminateResponder();
|
||||
// make sure all tests reset state machine tracking pointers on the mock surface
|
||||
@@ -52,9 +37,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture
|
||||
act(() => {
|
||||
@@ -76,9 +59,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
const buttons = [1, 2, 3, 4];
|
||||
// gesture
|
||||
@@ -105,9 +86,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
const acceptedModifierKeys = ['metaKey', 'shiftKey'];
|
||||
const ignoredModifierKeys = ['altKey', 'ctrlKey'];
|
||||
@@ -139,9 +118,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// touch gesture
|
||||
act(() => {
|
||||
@@ -186,9 +163,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture
|
||||
act(() => {
|
||||
@@ -245,9 +220,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start
|
||||
act(() => {
|
||||
@@ -302,9 +275,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start
|
||||
act(() => {
|
||||
@@ -355,9 +326,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start
|
||||
act(() => {
|
||||
@@ -426,9 +395,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start
|
||||
act(() => {
|
||||
@@ -475,9 +442,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start
|
||||
act(() => {
|
||||
@@ -526,9 +491,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start
|
||||
act(() => {
|
||||
@@ -596,9 +559,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start & move
|
||||
act(() => {
|
||||
@@ -653,9 +614,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start & move
|
||||
act(() => {
|
||||
@@ -707,9 +666,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start & move
|
||||
act(() => {
|
||||
@@ -779,9 +736,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start & move
|
||||
act(() => {
|
||||
@@ -830,9 +785,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start & move
|
||||
act(() => {
|
||||
@@ -882,9 +835,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start & move
|
||||
act(() => {
|
||||
@@ -943,9 +894,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start
|
||||
act(() => {
|
||||
@@ -987,9 +936,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start
|
||||
act(() => {
|
||||
@@ -1038,9 +985,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start
|
||||
act(() => {
|
||||
@@ -1067,9 +1012,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start
|
||||
act(() => {
|
||||
@@ -1134,9 +1077,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start
|
||||
act(() => {
|
||||
@@ -1181,9 +1122,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start & move
|
||||
act(() => {
|
||||
@@ -1228,9 +1167,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start & end
|
||||
act(() => {
|
||||
@@ -1273,9 +1210,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture
|
||||
act(() => {
|
||||
@@ -1320,9 +1255,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// gesture start & cancel
|
||||
act(() => {
|
||||
@@ -1359,9 +1292,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
const input = createEventTarget(inputRef.current);
|
||||
// getSelection is not supported in jest
|
||||
@@ -1389,9 +1320,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
const doc = createEventTarget(document);
|
||||
// getSelection is not supported in jest
|
||||
@@ -1437,9 +1366,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
const parent = createEventTarget(parentRef.current);
|
||||
// gesture start & scroll
|
||||
@@ -1473,9 +1400,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
const doc = createEventTarget(document);
|
||||
// gesture start & scroll
|
||||
@@ -1510,9 +1435,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
const sibling = createEventTarget(siblingRef.current);
|
||||
// gesture start & scroll
|
||||
@@ -1541,9 +1464,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
const doc = createEventTarget(document);
|
||||
// gesture start & blur
|
||||
@@ -1571,9 +1492,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
const win = createEventTarget(window);
|
||||
// gesture start & blur
|
||||
@@ -1607,9 +1526,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
const sibling = createEventTarget(siblingRef.current);
|
||||
// gesture start & blur
|
||||
@@ -1640,9 +1557,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// contextmenu sequence includes pointerdown "start"
|
||||
act(() => {
|
||||
@@ -1675,9 +1590,7 @@ describe('useResponderEvents', () => {
|
||||
}
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
const doc = createEventTarget(document);
|
||||
// contextmenu
|
||||
@@ -1860,9 +1773,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
|
||||
// gesture start
|
||||
@@ -2034,9 +1945,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
|
||||
// gesture start
|
||||
@@ -2199,9 +2108,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const parent = createEventTarget(parentRef.current);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
|
||||
@@ -2387,9 +2294,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
const sibling = createEventTarget(siblingRef.current);
|
||||
// gesture start on target
|
||||
@@ -2530,9 +2435,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
const sibling = createEventTarget(siblingRef.current);
|
||||
// gesture start and move on target
|
||||
@@ -2636,9 +2539,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
// first touch
|
||||
act(() => {
|
||||
@@ -2773,9 +2674,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
const parent = createEventTarget(parentRef.current);
|
||||
// first touch
|
||||
@@ -2876,9 +2775,7 @@ describe('useResponderEvents', () => {
|
||||
};
|
||||
|
||||
// render
|
||||
act(() => {
|
||||
render(<Component />);
|
||||
});
|
||||
render(<Component />);
|
||||
const target = createEventTarget(targetRef.current);
|
||||
act(() => {
|
||||
target.pointerdown({ pointerType });
|
||||
|
||||
@@ -8,21 +8,10 @@
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { render } from '@testing-library/react';
|
||||
import useStable from '..';
|
||||
|
||||
function createRoot(rootNode) {
|
||||
return {
|
||||
render(element) {
|
||||
ReactDOM.render(element, rootNode);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
describe('useStable', () => {
|
||||
let root;
|
||||
let rootNode;
|
||||
let spy = {};
|
||||
|
||||
const TestComponent = ({ initialValueCallback }): React.Node => {
|
||||
@@ -33,59 +22,33 @@ describe('useStable', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
spy = {};
|
||||
rootNode = document.createElement('div');
|
||||
document.body.appendChild(rootNode);
|
||||
root = createRoot(rootNode);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
root.render(null);
|
||||
document.body.removeChild(rootNode);
|
||||
rootNode = null;
|
||||
root = null;
|
||||
});
|
||||
|
||||
test('correctly sets the initial value', () => {
|
||||
const initialValueCallback = () => 5;
|
||||
act(() => {
|
||||
root.render(
|
||||
<TestComponent initialValueCallback={initialValueCallback} />
|
||||
);
|
||||
});
|
||||
render(<TestComponent initialValueCallback={initialValueCallback} />);
|
||||
expect(spy.value).toBe(5);
|
||||
});
|
||||
|
||||
test('does not change the value', () => {
|
||||
let counter = 0;
|
||||
const initialValueCallback = () => counter++;
|
||||
act(() => {
|
||||
root.render(
|
||||
<TestComponent initialValueCallback={initialValueCallback} />
|
||||
);
|
||||
});
|
||||
const { rerender } = render(
|
||||
<TestComponent initialValueCallback={initialValueCallback} />
|
||||
);
|
||||
expect(spy.value).toBe(0);
|
||||
act(() => {
|
||||
root.render(
|
||||
<TestComponent initialValueCallback={initialValueCallback} />
|
||||
);
|
||||
});
|
||||
rerender(<TestComponent initialValueCallback={initialValueCallback} />);
|
||||
expect(spy.value).toBe(0);
|
||||
});
|
||||
|
||||
test('only calls the callback once', () => {
|
||||
let counter = 0;
|
||||
const initialValueCallback = () => counter++;
|
||||
act(() => {
|
||||
root.render(
|
||||
<TestComponent initialValueCallback={initialValueCallback} />
|
||||
);
|
||||
});
|
||||
const { rerender } = render(
|
||||
<TestComponent initialValueCallback={initialValueCallback} />
|
||||
);
|
||||
expect(counter).toBe(1);
|
||||
act(() => {
|
||||
root.render(
|
||||
<TestComponent initialValueCallback={initialValueCallback} />
|
||||
);
|
||||
});
|
||||
rerender(<TestComponent initialValueCallback={initialValueCallback} />);
|
||||
expect(counter).toBe(1);
|
||||
});
|
||||
|
||||
@@ -98,17 +61,11 @@ describe('useStable', () => {
|
||||
}
|
||||
return counter++;
|
||||
};
|
||||
act(() => {
|
||||
root.render(
|
||||
<TestComponent initialValueCallback={initialValueCallback} />
|
||||
);
|
||||
});
|
||||
const { rerender } = render(
|
||||
<TestComponent initialValueCallback={initialValueCallback} />
|
||||
);
|
||||
expect(spy.value).toBe(null);
|
||||
act(() => {
|
||||
root.render(
|
||||
<TestComponent initialValueCallback={initialValueCallback} />
|
||||
);
|
||||
});
|
||||
rerender(<TestComponent initialValueCallback={initialValueCallback} />);
|
||||
expect(spy.value).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
import AnimatedValue from './nodes/AnimatedValue';
|
||||
import NativeAnimatedHelper from './NativeAnimatedHelper';
|
||||
import findNodeHandle from '../../../exports/findNodeHandle';
|
||||
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
|
||||
@@ -58,11 +57,10 @@ export function attachNativeEvent(
|
||||
// Assume that the event containing `nativeEvent` is always the first argument.
|
||||
traverse(argMapping[0].nativeEvent, []);
|
||||
|
||||
const viewTag = findNodeHandle(viewRef);
|
||||
if (viewTag != null) {
|
||||
if (viewRef != null) {
|
||||
eventMappings.forEach(mapping => {
|
||||
NativeAnimatedHelper.API.addAnimatedEventToView(
|
||||
viewTag,
|
||||
viewRef,
|
||||
eventName,
|
||||
mapping,
|
||||
);
|
||||
@@ -71,10 +69,10 @@ export function attachNativeEvent(
|
||||
|
||||
return {
|
||||
detach() {
|
||||
if (viewTag != null) {
|
||||
if (viewRef != null) {
|
||||
eventMappings.forEach(mapping => {
|
||||
NativeAnimatedHelper.API.removeAnimatedEventFromView(
|
||||
viewTag,
|
||||
viewRef,
|
||||
eventName,
|
||||
// $FlowFixMe[incompatible-call]
|
||||
mapping.animatedValueTag,
|
||||
|
||||
@@ -14,7 +14,6 @@ import {AnimatedEvent} from '../AnimatedEvent';
|
||||
import AnimatedNode from './AnimatedNode';
|
||||
import AnimatedStyle from './AnimatedStyle';
|
||||
import NativeAnimatedHelper from '../NativeAnimatedHelper';
|
||||
import findNodeHandle from '../../../../exports/findNodeHandle';
|
||||
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
|
||||
@@ -119,9 +118,7 @@ class AnimatedProps extends AnimatedNode {
|
||||
|
||||
__connectAnimatedView(): void {
|
||||
invariant(this.__isNative, 'Expected node to be marked as "native"');
|
||||
const nativeViewTag: ?number = findNodeHandle(
|
||||
this._animatedView,
|
||||
);
|
||||
const nativeViewTag: ?number = this._animatedView
|
||||
invariant(
|
||||
nativeViewTag != null,
|
||||
'Unable to locate attached view in the native tree',
|
||||
@@ -134,9 +131,7 @@ class AnimatedProps extends AnimatedNode {
|
||||
|
||||
__disconnectAnimatedView(): void {
|
||||
invariant(this.__isNative, 'Expected node to be marked as "native"');
|
||||
const nativeViewTag: ?number = findNodeHandle(
|
||||
this._animatedView,
|
||||
);
|
||||
const nativeViewTag: ?number = this._animatedView
|
||||
invariant(
|
||||
nativeViewTag != null,
|
||||
'Unable to locate attached view in the native tree',
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
import Batchinator from '../Batchinator';
|
||||
import FillRateHelper from '../FillRateHelper';
|
||||
import findNodeHandle from '../../../exports/findNodeHandle';
|
||||
import RefreshControl from '../../../exports/RefreshControl';
|
||||
import ScrollView from '../../../exports/ScrollView';
|
||||
import StyleSheet from '../../../exports/StyleSheet';
|
||||
@@ -573,7 +572,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
if (this._scrollRef && this._scrollRef.getScrollableNode) {
|
||||
return this._scrollRef.getScrollableNode();
|
||||
} else {
|
||||
return findNodeHandle(this._scrollRef);
|
||||
return this._scrollRef;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user