mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Fixed ReactNativeFiber event handling regression (#8959)
* Fixed ReactNativeFiber event system regression introduced in b354db2
Also added test coverage to ReactNativeEvents-test for Fiber
* ReactNative tests now run against fiber renderer when env flag set
Updated the test-framework-setup file so that record-tests runs native tests against ReactNativeFiber. ReactComponentTreeHook native tests all now fail but that's expected.
* Avoid calling setChildren() if no children
This commit is contained in:
@@ -61,6 +61,55 @@ src/renderers/__tests__/ReactComponentTreeHook-test.js
|
||||
* registers inlined text nodes
|
||||
* works
|
||||
|
||||
src/renderers/__tests__/ReactComponentTreeHook-test.native.js
|
||||
* uses displayName or Unknown for classic components
|
||||
* uses displayName, name, or ReactComponent for modern components
|
||||
* uses displayName, name, or Object for factory components
|
||||
* uses displayName, name, or StatelessComponent for functional components
|
||||
* reports a host tree correctly
|
||||
* reports a simple tree with composites correctly
|
||||
* reports a tree with composites correctly
|
||||
* ignores null children
|
||||
* ignores false children
|
||||
* reports text nodes as children
|
||||
* reports a single text node as a child
|
||||
* reports a single number node as a child
|
||||
* reports a zero as a child
|
||||
* skips empty nodes for multiple children
|
||||
* updates text of a single text child
|
||||
* updates from no children to a single text child
|
||||
* updates from a single text child to no children
|
||||
* updates from no children to multiple text children
|
||||
* updates from multiple text children to no children
|
||||
* updates from one text child to multiple text children
|
||||
* updates from multiple text children to one text child
|
||||
* updates text nodes when reordering
|
||||
* updates host nodes when reordering with keys
|
||||
* updates host nodes when reordering with keys
|
||||
* updates a single composite child of a different type
|
||||
* updates a single composite child of the same type
|
||||
* updates from no children to a single composite child
|
||||
* updates from a single composite child to no children
|
||||
* updates mixed children
|
||||
* updates with a host child
|
||||
* updates from null to a host child
|
||||
* updates from a host child to null
|
||||
* updates from a host child to a composite child
|
||||
* updates from a composite child to a host child
|
||||
* updates from null to a composite child
|
||||
* updates from a composite child to null
|
||||
* updates with a host child
|
||||
* updates from null to a host child
|
||||
* updates from a host child to null
|
||||
* updates from a host child to a composite child
|
||||
* updates from a composite child to a host child
|
||||
* updates from null to a composite child
|
||||
* updates from a composite child to null
|
||||
* tracks owner correctly
|
||||
* purges unmounted components automatically
|
||||
* reports update counts
|
||||
* does not report top-level wrapper as a root
|
||||
|
||||
src/renderers/__tests__/ReactCompositeComponent-test.js
|
||||
* should warn about `forceUpdate` on unmounted components
|
||||
* should warn about `setState` on unmounted components
|
||||
|
||||
@@ -558,55 +558,6 @@ src/renderers/__tests__/ReactComponentTreeHook-test.js
|
||||
* is created during mounting
|
||||
* is created when calling renderToString during render
|
||||
|
||||
src/renderers/__tests__/ReactComponentTreeHook-test.native.js
|
||||
* uses displayName or Unknown for classic components
|
||||
* uses displayName, name, or ReactComponent for modern components
|
||||
* uses displayName, name, or Object for factory components
|
||||
* uses displayName, name, or StatelessComponent for functional components
|
||||
* reports a host tree correctly
|
||||
* reports a simple tree with composites correctly
|
||||
* reports a tree with composites correctly
|
||||
* ignores null children
|
||||
* ignores false children
|
||||
* reports text nodes as children
|
||||
* reports a single text node as a child
|
||||
* reports a single number node as a child
|
||||
* reports a zero as a child
|
||||
* skips empty nodes for multiple children
|
||||
* updates text of a single text child
|
||||
* updates from no children to a single text child
|
||||
* updates from a single text child to no children
|
||||
* updates from no children to multiple text children
|
||||
* updates from multiple text children to no children
|
||||
* updates from one text child to multiple text children
|
||||
* updates from multiple text children to one text child
|
||||
* updates text nodes when reordering
|
||||
* updates host nodes when reordering with keys
|
||||
* updates host nodes when reordering with keys
|
||||
* updates a single composite child of a different type
|
||||
* updates a single composite child of the same type
|
||||
* updates from no children to a single composite child
|
||||
* updates from a single composite child to no children
|
||||
* updates mixed children
|
||||
* updates with a host child
|
||||
* updates from null to a host child
|
||||
* updates from a host child to null
|
||||
* updates from a host child to a composite child
|
||||
* updates from a composite child to a host child
|
||||
* updates from null to a composite child
|
||||
* updates from a composite child to null
|
||||
* updates with a host child
|
||||
* updates from null to a host child
|
||||
* updates from a host child to null
|
||||
* updates from a host child to a composite child
|
||||
* updates from a composite child to a host child
|
||||
* updates from null to a composite child
|
||||
* updates from a composite child to null
|
||||
* tracks owner correctly
|
||||
* purges unmounted components automatically
|
||||
* reports update counts
|
||||
* does not report top-level wrapper as a root
|
||||
|
||||
src/renderers/__tests__/ReactCompositeComponent-test.js
|
||||
* should support module pattern components
|
||||
* should support rendering to different child types over time
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// We want to globally mock this but jest doesn't let us do that by default
|
||||
// for a file that already exists. So we have to explicitly mock it.
|
||||
jest.mock('ReactDOM');
|
||||
jest.mock('ReactNative');
|
||||
jest.mock('ReactDOMFeatureFlags', () => {
|
||||
const flags = require.requireActual('ReactDOMFeatureFlags');
|
||||
return Object.assign({}, flags, {
|
||||
@@ -15,6 +16,12 @@ jest.mock('ReactFeatureFlags', () => {
|
||||
disableNewFiberFeatures: true,
|
||||
});
|
||||
});
|
||||
jest.mock('ReactNativeFeatureFlags', () => {
|
||||
const flags = require.requireActual('ReactNativeFeatureFlags');
|
||||
return Object.assign({}, flags, {
|
||||
useFiber: flags.useFiber || !!process.env.REACT_DOM_JEST_USE_FIBER,
|
||||
});
|
||||
});
|
||||
|
||||
// Error logging varies between Fiber and Stack;
|
||||
// Rather than fork dozens of tests, mock the error-logging file by default.
|
||||
|
||||
@@ -66,8 +66,8 @@ function getTagFromInstance(inst) {
|
||||
return tag;
|
||||
}
|
||||
|
||||
function getFiberEventHandlersFromTag(tag) {
|
||||
return instanceProps[tag] || null;
|
||||
function getFiberCurrentPropsFromNode(stateNode) {
|
||||
return instanceProps[stateNode._nativeTag] || null;
|
||||
}
|
||||
|
||||
function updateFiberProps(tag, props) {
|
||||
@@ -82,7 +82,7 @@ var ReactNativeComponentTree = {
|
||||
precacheNode,
|
||||
uncacheFiberNode,
|
||||
uncacheNode,
|
||||
getFiberCurrentPropsFromNode: getFiberEventHandlersFromTag,
|
||||
getFiberCurrentPropsFromNode,
|
||||
updateFiberProps,
|
||||
};
|
||||
|
||||
|
||||
@@ -213,6 +213,11 @@ const NativeRenderer = ReactFiberReconciler({
|
||||
props : Props,
|
||||
rootContainerInstance : Container,
|
||||
) : boolean {
|
||||
// Don't send a no-op message over the bridge.
|
||||
if (parentInstance._children.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Map from child objects to native tags.
|
||||
// Either way we need to pass a copy of the Array to prevent it from being frozen.
|
||||
const nativeTags = parentInstance._children.map(
|
||||
|
||||
@@ -42,7 +42,6 @@ it('handles events', () => {
|
||||
uiViewClassName: 'View',
|
||||
});
|
||||
|
||||
|
||||
var log = [];
|
||||
ReactNative.render(
|
||||
<View
|
||||
@@ -63,7 +62,12 @@ it('handles events', () => {
|
||||
);
|
||||
|
||||
expect(UIManager.createView.mock.calls.length).toBe(2);
|
||||
var innerTag = UIManager.createView.mock.calls[1][0];
|
||||
|
||||
// Don't depend on the order of createView() calls.
|
||||
// Stack creates views outside-in; fiber creates them inside-out.
|
||||
var innerTag = UIManager.createView.mock.calls.find(
|
||||
args => args[3].foo === 'inner'
|
||||
)[0];
|
||||
|
||||
EventEmitter.receiveTouches(
|
||||
'topTouchStart',
|
||||
|
||||
@@ -18,6 +18,8 @@ var UIManager;
|
||||
|
||||
describe('ReactNative', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
|
||||
React = require('React');
|
||||
ReactNative = require('ReactNative');
|
||||
UIManager = require('UIManager');
|
||||
@@ -45,17 +47,17 @@ describe('ReactNative', () => {
|
||||
|
||||
ReactNative.render(<View foo="foo" />, 11);
|
||||
|
||||
expect(UIManager.createView.mock.calls.length).toBe(2);
|
||||
expect(UIManager.setChildren.mock.calls.length).toBe(2);
|
||||
expect(UIManager.createView.mock.calls.length).toBe(1);
|
||||
expect(UIManager.setChildren.mock.calls.length).toBe(1);
|
||||
expect(UIManager.manageChildren).not.toBeCalled();
|
||||
expect(UIManager.updateView).not.toBeCalled();
|
||||
|
||||
ReactNative.render(<View foo="bar" />, 11);
|
||||
|
||||
expect(UIManager.createView.mock.calls.length).toBe(2);
|
||||
expect(UIManager.setChildren.mock.calls.length).toBe(2);
|
||||
expect(UIManager.createView.mock.calls.length).toBe(1);
|
||||
expect(UIManager.setChildren.mock.calls.length).toBe(1);
|
||||
expect(UIManager.manageChildren).not.toBeCalled();
|
||||
expect(UIManager.updateView).toBeCalledWith(3, 'View', { foo: 'bar' });
|
||||
expect(UIManager.updateView).toBeCalledWith(2, 'View', { foo: 'bar' });
|
||||
});
|
||||
|
||||
it('returns the correct instance and calls it in the callback', () => {
|
||||
|
||||
Reference in New Issue
Block a user