Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not define components during render #11536

Closed
3 of 12 tasks
jbrodriguez opened this issue Aug 14, 2023 · 12 comments
Closed
3 of 12 tasks

Do not define components during render #11536

jbrodriguez opened this issue Aug 14, 2023 · 12 comments

Comments

@jbrodriguez
Copy link

Current behavior

the app works, but we get an eslint 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 “Tabs” and pass data as props. If you want to allow component creation in props, set allowAsProps option to true

this is the code

<Tab.Navigator
  screenOptions={({ route }) => ({
    tabBarIcon: (props) => <TabItem name={route.name} {...props} />,
    headerShown: false,
  })}
>
  <Tab.Screen name="One" component={One} />
  <Tab.Screen name="Two" component={Two} />
</Tab.Navigator>

i need to pass the route.name in order to set the icon and need props due to the focused property

any thoughts ?

Expected behavior

we shouldn't receive an eslint warning

Reproduction

https://github.com/react-navigation/react-navigation

Platform

  • Android
  • iOS
  • Web
  • Windows
  • MacOS

Packages

  • @react-navigation/bottom-tabs
  • @react-navigation/drawer
  • @react-navigation/material-top-tabs
  • @react-navigation/stack
  • @react-navigation/native-stack
  • react-native-tab-view

Environment

  • I've removed the packages that I don't use
package version
@react-navigation/native 6.1.7
@react-navigation/bottom-tabs 6.5.8
@react-navigation/drawer 6.6.3
@react-navigation/native-stack 6.9.13
react-native-safe-area-context 4.7.1
react-native-screens 3.24.0
react-native-gesture-handler 2.9.0
react-native-reanimated 3.4.2
react-native-tab-view 3.1.1
react-native-pager-view 6.2.0
react-native 0.71.12
node 18.16.0
npm or yarn 1.22.19
@github-actions
Copy link

Hey @jbrodriguez! Thanks for opening the issue. It seems that the issue doesn't contain a link to a repro.

The best way to get attention to your issue is to provide an easy way for a developer to reproduce the issue.

You can provide a repro using any of the following:

A snack link is preferred since it's the easiest way to both create and share a repro. If it's not possible to create a repro using a snack, link to a GitHub repo under your username is a good alternative. Don't link to a branch or specific file etc. as it won't be detected.

Try to keep the repro as small as possible by narrowing down the minimal amount of code needed to reproduce the issue. Don't link to your entire project or a project containing code unrelated to the issue. See "How to create a Minimal, Reproducible Example" for more information.

You can edit your original issue to include a link to the repro, or leave it as a comment. The issue will be closed automatically after a while if you don't provide a repro.

@github-actions
Copy link

The versions mentioned in the issue for the following packages differ from the latest versions on npm:

  • react-native-tab-view (found: 3.1.1, latest: 3.5.2)

Can you verify that the issue still exists after upgrading to the latest versions of these packages?

@jbrodriguez
Copy link
Author

thank you, the react-native-tab-view component is not active in relation to the issue presented

@satya164
Copy link
Member

You're getting warning from the ESLint rules you're using, it's not a bug in React Navigation. The options like tabBarIcon are functions that return a React element, while they look similar to components, they aren't used as components so the warning is a false positive.

@github-actions
Copy link

Hey! This issue is closed and isn't watched by the core team. You are welcome to discuss the issue with others in this thread, but if you think this issue is still valid and needs to be tracked, please open a new issue with a repro.

@nihilenz
Copy link

You're getting warning from the ESLint rules you're using, it's not a bug in React Navigation. The options like tabBarIcon are functions that return a React element, while they look similar to components, they aren't used as components so the warning is a false positive.

Hello, the same happens when you use navigation.setOptions to update a button (in this use case https://reactnavigation.org/docs/header-buttons/#header-interaction-with-its-screen-component). Can we ignore the warning?

@satya164
Copy link
Member

You're getting warning from the ESLint rules you're using, it's not a bug in React Navigation. The options like tabBarIcon are functions that return a React element, while they look similar to components, they aren't used as components so the warning is a false positive.

Hello, the same happens when you use navigation.setOptions to update a button (in this use case https://reactnavigation.org/docs/header-buttons/#header-interaction-with-its-screen-component). Can we ignore the warning?

Yes

@VariabileAleatoria
Copy link

while they look similar to components, they aren't used as components so the warning is a false positive.

Care to elaborate why?

@satya164
Copy link
Member

@VariabileAleatoria

Care to elaborate why?

Components are used like <ComponentName />. React Navigation doesn't use tabBarIcon like that, it's called as a function (tabBarIcon()).

@VariabileAleatoria
Copy link

@VariabileAleatoria

Care to elaborate why?

Components are used like <ComponentName />. React Navigation doesn't use tabBarIcon like that, it's called as a function (tabBarIcon()).

Being React Components functions that takes props and returns JSX I don't understand what the difference is and above all why the warning should be a false positive.

@satya164
Copy link
Member

@VariabileAleatoria returning JSX doesn't make something a component. whether something is a component or not doesn't depend how the definition looks, but how it is used - if it's not used like <ComponentName />/with React.createElement then it's not a component.

@mateoLorenzo
Copy link

I fixed this warning passing a function to tabBarIcon instead of a component:

const renderTabIcon = (name: string, color: string) => {
  return <Icon name={name} size={25} color={color} />;
};

<Tab.Screen
   options={{
      title: 'Home',
      tabBarIcon: ({color}) => renderTabIcon('home-outline', color),
   }}
   name="HomeScreen"
   component={HomeScreen}
/>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants