Skip to content

Using Context breaks components with setState in React Native 0.54 #18351

Description

@satya164

React Native uses React 16.3.0-alpha.1 which has the new context API. However, there's a bug in the context API which makes the consumer re-render its children every time one of its children call setState: react/react#12218

This breaks components like FlatList which call setState internally where you get a stack overflow due to re-render happening thousands of times. The workaround is to wrap FlatList with a PureComponent to short-circuit the updates.

It seems to have been fixed here: react/react#12254, so we would need to update the React version used by React Native once it's released.

Environment

Environment:
OS: macOS High Sierra 10.13.4
Node: 9.5.0
Yarn: 1.3.2
npm: 5.6.0
Watchman: 4.9.0
Xcode: Xcode 9.2 Build version 9C40b
Android Studio: 2.3 AI-162.4069837

Packages: (wanted => installed)
react: ^16.3.0-alpha.1 => 16.3.0-alpha.1
react-native: 0.54.2 => 0.54.2

Expected Behavior

Should not cause a stack overflow.

Actual Behavior

Causes a stack overflow.

Steps to Reproduce

It's not possible to provide a Snack since it uses an older version of React Native. You can create a new project with react-native init and copy the following code to App.js:

import * as React from 'react';
import { Text, FlatList } from 'react-native';

const { Consumer } = React.createContext({});

export default class App extends React.Component {
  render() {
    return (
      <Consumer>
        {() => {
          console.log('re-rendered');

          return (
            <FlatList
              data={Array.from({ length: 100 }).map((_, i) => `Item ${1}`)}
              renderItem={({ item }) => <Text>{item}</Text>}
              keyExtractor={(item, index) => 'key' + index}
            />
          );
        }}
      </Consumer>
    );
  }
}

Activity

  1. hramos commented on Mar 13, 2018

    @hramos
    Contributor

    I have a diff out that should sync these changes into React Native. Since this was not caught by our current test suite, it would be a good idea to add a test here to catch any regressions in the future.

  2. added a commit that references this issue on Mar 13, 2018
  3. hramos commented on Mar 13, 2018

    @hramos
    Contributor

    Repro'd on a new project:

    simulator screen shot - iphone 6 - 2018-03-13 at 11 35 59

    Environment:
    OS: macOS High Sierra 10.13.3
    Node: 8.9.3
    Yarn: 1.2.0
    npm: 5.6.0
    Watchman: 4.9.1
    Xcode: Xcode 9.2 Build version 9C40b
    Android Studio: 3.0 AI-171.4443003

    Packages: (wanted => installed)
    react: ^16.3.0-alpha.1 => 16.3.0-alpha.1
    react-native: 0.54.2 => 0.54.2

  4. hramos commented on Mar 14, 2018

    @hramos
    Contributor

    The React <-> React Native sync has landed in 4f8328b. Can you take a look and see if this still happens?

  5. hramos commented on Mar 14, 2018

    @hramos
    Contributor

    Here's the regression test in RNTester: #18382

    If you agree my test plan in that PR is solid, then that should serve as a confirmation that this issue has been solved. Please re-open if you find that's not the case.

  6. SASoto commented on Jul 8, 2018

    @SASoto

    Has this issue been fixed? I am currently using version 0.55.4 of react native and am encountering a similar issue to the one expressed in callstack/react-native-paper#272
    I am working with a FlatlList wrapped by a ScrollView, wrapped by a Modal.

  7. hramos commented on Jul 16, 2018

    @hramos
    Contributor

    0.56 is the latest version, and it has this fix.

  8. locked as resolved and limited conversation to collaborators on Mar 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions