From 10b642a7af097bd508dab7b5d4723ccb4339d35f Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Wed, 14 Feb 2018 07:51:52 -0800 Subject: [PATCH] Verify that the component passed to createAnimatedComponent is not functional Summary: Stateless functional components don't support refs and we need that for the component to work, it used to crash with this error message: `undefined is not an object (evaluating 'this._component.getScrollableNode')`. This makes it clear what the issue is. Fixes some of the errors in #10635, not sure if it fixes all the cases described in the issue though. **Test plan** Tested that passing a component with createClass or extends Component works but passing a function causes an error. [GENERAL] [ENHANCEMENT] [Animated] - Verify that the component passed to createAnimatedComponent is not functional Closes https://github.com/facebook/react-native/pull/15019 Differential Revision: D6988096 Pulled By: sahrens fbshipit-source-id: ec0ffa763245e786f44b4a1d56c0738876c25782 --- Libraries/Animated/src/__tests__/AnimatedNative-test.js | 9 ++++++--- Libraries/Animated/src/createAnimatedComponent.js | 9 +++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Libraries/Animated/src/__tests__/AnimatedNative-test.js b/Libraries/Animated/src/__tests__/AnimatedNative-test.js index d3f59368ea6098..62c40c8388d79b 100644 --- a/Libraries/Animated/src/__tests__/AnimatedNative-test.js +++ b/Libraries/Animated/src/__tests__/AnimatedNative-test.js @@ -10,11 +10,14 @@ */ 'use strict'; +const ClassComponentMock = class {}; +ClassComponentMock.prototype.isReactComponent = true; + jest .clearAllMocks() - .setMock('Text', {}) - .setMock('View', {}) - .setMock('Image', {}) + .setMock('Text', ClassComponentMock) + .setMock('View', ClassComponentMock) + .setMock('Image', ClassComponentMock) .setMock('React', {Component: class {}}) .setMock('NativeModules', { NativeAnimatedModule: {}, diff --git a/Libraries/Animated/src/createAnimatedComponent.js b/Libraries/Animated/src/createAnimatedComponent.js index fd363ff0ca7495..42110be681988c 100644 --- a/Libraries/Animated/src/createAnimatedComponent.js +++ b/Libraries/Animated/src/createAnimatedComponent.js @@ -17,7 +17,16 @@ const AnimatedProps = require('./nodes/AnimatedProps'); const React = require('React'); const ViewStylePropTypes = require('ViewStylePropTypes'); +const invariant = require('fbjs/lib/invariant'); + function createAnimatedComponent(Component: any): any { + invariant( + typeof Component === 'string' || + (Component.prototype && Component.prototype.isReactComponent), + '`createAnimatedComponent` does not support stateless functional components; ' + + 'use a class component instead.', + ); + class AnimatedComponent extends React.Component { _component: any; _invokeAnimatedPropsCallbackOnMount: boolean = false;