facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
119.26k stars 24.35k forks source link

Flatlist results in invalid hook call in a Jest test #32808

Closed jayshah-swiggy closed 2 years ago

jayshah-swiggy commented 2 years ago

New Version

0.66.3

Old Version

0.63.2

Build Target(s)

jest

Output of react-native info

System: OS: macOS 11.6 CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz Memory: 91.69 MB / 16.00 GB Shell: 3.2.57 - /bin/bash Binaries: Node: 14.18.0 - ~/.nvm/versions/node/v14.18.0/bin/node Yarn: 1.22.17 - /usr/local/bin/yarn npm: 6.14.15 - ~/.nvm/versions/node/v14.18.0/bin/npm Watchman: 2021.10.18.00 - /usr/local/bin/watchman Managers: CocoaPods: 1.11.2 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: DriverKit 21.0.1, iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0 Android SDK: API Levels: 23, 25, 26, 27, 28, 29, 30, 31 Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.2, 31.0.0 System Images: android-29 | Google Play Intel x86 Atom Android NDK: 20.1.5948944 IDEs: Android Studio: 2020.3 AI-203.7717.56.2031.7678000 Xcode: 13.1/13A1030d - /usr/bin/xcodebuild Languages: Java: 1.8.0_292 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 17.0.2 => 17.0.2 react-native: 0.66.3 => 0.66.3 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found

Issue and Reproduction Steps

Just run npm install and npm test in https://github.com/jayshah-swiggy/invalidhookflatlistbug

The app implementaiton is really simple (it includes a FlatList from the samples):

class App extends React.Component {

  renderItem = ({ item }) => (
    <Item title={item.title} />
  );

  render(){
    const backgroundStyle = {
      backgroundColor:  Colors.lighter,
    };
    const DATA = [
      {
        id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
        title: 'First Item',
      },
      {
        id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
        title: 'Second Item',
      },
      {
        id: '58694a0f-3da1-471f-bd96-145571e29d72',
        title: 'Third Item',
      },
    ];

    return (
      <SafeAreaView style={backgroundStyle}>
        <StatusBar barStyle={'light-content'} />
        <FlatList
          data={DATA}
          renderItem={this.renderItem}
          keyExtractor={item => item.id}
      />
      </SafeAreaView>
    );
  }
};

and the test is also really simple:

import React from 'react';
import renderer from 'react-test-renderer';
import App from './App';

describe('App component', () => {
    beforeEach(() => {
        jest.resetModules();
        jest.resetAllMocks();
    });

    it("render App", () => {
        const tree = renderer.create(<App />).toJSON();
        expect(tree).toMatchSnapshot();      
    });
});

Showing following error:


  ● App component › render App

    Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
    1. You might have mismatching versions of React and the renderer (such as React DOM)
    2. You might be breaking the Rules of Hooks
    3. You might have more than one copy of React in the same app
    See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.```
jayshah-swiggy commented 2 years ago

There are two solutions to this: either stop calling jest.resetModules(); Or require react and react-test-renderer separately in each test.