Shan Biswas
Shan Biswas

Reputation: 429

React native eslint-disable-next-line react/no-unstable-nested-components

I am using a custom back button in the headerLeft. I have enabled ESLINT, and it is showing the below warning.

Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component “App” and pass data as props. If you want to allow component creation in props, set allowAsProps option to true.eslintreact/no-unstable-nested-components

App.tsx

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 */

import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createDrawerNavigator} from '@react-navigation/drawer';
import {StatusBar, useColorScheme} from 'react-native';

import {Colors} from 'react-native/Libraries/NewAppScreen';

import {useNavigation} from '@react-navigation/native';

import {DrawerContent} from './src/navigation/drawer-content';
import {Button} from 'react-native-paper';

import Feed from './src/screens/feed';
import Article from './src/screens/article';

const Drawer = createDrawerNavigator();

const CustomDrawer = (props: any) => {
  return <DrawerContent {...props} />;
};

const BackButton = () => {
  const navigation = useNavigation();
  return (
    <Button
      icon="arrow-left-thick"
      onPress={() => navigation.goBack()}
      children={undefined}
    />
  );
};

function App(): JSX.Element {
  const isDarkMode = useColorScheme() === 'dark';

  const backgroundStyle = {
    backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
  };

  return (
    <NavigationContainer>
      {/* <SafeAreaView style={backgroundStyle}> */}
      <StatusBar
        barStyle={isDarkMode ? 'light-content' : 'dark-content'}
        backgroundColor={backgroundStyle.backgroundColor}
      />
      <Drawer.Navigator drawerContent={CustomDrawer} initialRouteName="Feed">
        <Drawer.Screen name="Feed" component={Feed} />
        <Drawer.Screen
          name="Article"
          component={Article}
          options={{
            title: 'Timeline',
            headerLeft: () => <BackButton />,
          }}
        />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}

export default App;

Upvotes: 2

Views: 1884

Answers (2)

ChillyPenguin
ChillyPenguin

Reputation: 1180

If you're not passing any props to <BackButton />, which you're not, then this should work:

<Drawer.Screen
  name="Article"
  component={Article}
  options={{
    title: 'Timeline',
    headerLeft: BackButton
  }}

BackButton is a function that returns a component, i.e. <BackButton />. So your anonymous function isn't necessary,

Upvotes: 1

Shyam Mittal
Shyam Mittal

Reputation: 353

It could be because of the following eslint rule react/no-unstable-nested-components.

I guess according to react-navigation's guide you have defined the headerLeft prop but the above eslint rule contradicts that.

Contradiction occurred here:

<Drawer.Screen
  name="Article"
  component={Article}
  options={{
    title: 'Timeline',
    headerLeft: () => <BackButton />, // <--- this line
  }}
/>

Possible fix(es):

  1. Disable plugin for the file: // eslint-disable react/no-unstable-nested-components (or for just one line)
  2. Move component definition out of the component.
  3. Edit the .eslintrc to allow component as props in this rule's settings
...
"react/no-unstable-nested-components": [
 "off" | "warn" | "error",
 { "allowAsProps": true | false }
]
...

Upvotes: 3

Related Questions