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

Tab.screen has always re-render when switch tabs #10174

Closed
2 of 11 tasks
bumjin1013 opened this issue Dec 1, 2021 · 28 comments
Closed
2 of 11 tasks

Tab.screen has always re-render when switch tabs #10174

bumjin1013 opened this issue Dec 1, 2021 · 28 comments

Comments

@bumjin1013
Copy link

Current behavior

I'm using TopTabNavigator from '@react-navigation/material-top-tabs.
When i switch tab screen, the components are re-rendered at once again.

<Tab.screen
component={console.log('first component')}
/>
<Tab.screen
component={console.log('second component')}
/>
<Tab.screen
component={console.log('third component')}
/>

Every time swich tabs, all console logs are executed at once

Expected behavior

I want prevent re-rerendering, just render only once

Reproduction

https://github.com/bumjin1013/node-react-food-delivery.git

Platform

  • Android
  • iOS
  • Web
  • Windows
  • MacOS

Packages

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

Environment

package version
@react-navigation/native
@react-navigation/bottom-tabs
@react-navigation/drawer
@react-navigation/material-bottom-tabs
@react-navigation/material-top-tabs
@react-navigation/stack
@react-navigation/native-stack
react-native-safe-area-context
react-native-screens
react-native-gesture-handler
react-native-reanimated
react-native-tab-view
react-native-pager-view
react-native
expo
node
npm or yarn
@bumjin1013 bumjin1013 added the bug label Dec 1, 2021
@github-actions
Copy link

github-actions bot commented Dec 1, 2021

Couldn't find version numbers for the following packages in the issue:

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

Can you update the issue to include version numbers for those packages? The version numbers must match the format 1.2.3.

@sergeymorkovkin
Copy link

@bumjin1013 We are facing same issue on iOS. Were you able to work around this?

@Jamal-ReachFirst

This comment was marked as spam.

@Jamal-ReachFirst
Copy link

Jamal-ReachFirst commented Nov 29, 2022

All the screens get rendered while switching b/w tabs(@react-navigation/material-top-tabs).

@sanduluca
Copy link

Same here. All of the tabs are re-redering when I switch between them

@williamliangwl
Copy link

same here, facing same issue in both Android + iOS, using the bottom tab https://reactnavigation.org/docs/5.x/bottom-tab-navigator

@github-actions
Copy link

github-actions bot commented Dec 5, 2022

Hey! Thanks for opening the issue. Can you provide a minimal repro which demonstrates the issue? Posting a snippet of your code in the issue is useful, but it's not usually straightforward to run. A repro will help us debug the issue faster. Please try to keep the repro as small as possible and make sure that we can run it without additional setup.

The easiest way to provide a repro is on snack.expo.dev. If it's not possible to repro it on snack.expo.dev, then please provide the repro in a GitHub repository.

@Jamal-ReachFirst
Copy link

Did anyone figure out why this happening???

@github-actions
Copy link

Hello 👋, this issue has been open for more than a month without a repro or any activity. If the issue is still present in the latest version, please provide a repro or leave a comment within 7 days to keep it open, otherwise it will be closed automatically. If you found a solution or workaround for the issue, please comment here for others to find. If this issue is critical for you, please consider sending a pull request to fix it.

@github-actions github-actions bot added the stale label Jan 14, 2023
@raajnadar
Copy link
Member

Please read this doc -> https://reactnavigation.org/docs/troubleshooting#screens-are-unmountingremounting-during-navigation

If you still have an issue, please give a snack repro that renders a component, not a console.log, in your case console.log is seen as a new change on each render & it is fired every time you switch tab

@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.

@Jamal-ReachFirst
Copy link

Why is this closed?

@sanduluca
Copy link

Why did you closed it ? @raajnadar
Too much people report the problem and you still think no one of them didn't read the docs ?

@raajnadar
Copy link
Member

raajnadar commented Jan 14, 2023

This issue is open for a long time without a minimal reproducer, you cannot expect maintainers to dig into your codebase to find the bug nor the version are added correctly to see if the issue is solved in the latest versions

@sanduluca why don't you provide a minimal reproducer? I am happy to reopen the issue if you can provide one

@constantinescu-vlad
Copy link

Here I have a simple tab navigator inside a stack navigator. Whenever I switch tabs I get this re-render:

StaticContainer
whyDidYouRender.js:690
{StaticContainer: ƒ}
'Re-rendered because of props changes:'
whyDidYouRender.js:704 props.route
whyDidYouRender.js:705 different objects that are equal by value. (more info at http://bit.ly/wdyr02)
whyDidYouRender.js:706
{prev route: {…}}
prev route
:
{key: 'tabs-1WgYOk1PVEjotvjQYTwqC', name: 'tabs', params: undefined}
[[Prototype]]
:
Object
'!=='
{next route: {…}}
next route
:
{key: 'tabs-1WgYOk1PVEjotvjQYTwqC', name: 'tabs', params: undefined}
[[Prototype]]
:
Object

const TabNav = createBottomTabNavigator();

const renderTabBarButton = props => {
    return (
        <TouchableOpacity {...props}>
            <Text style={{color: 'red'}}>{props.to}</Text>
        </TouchableOpacity>
    )
}

const TAB_OPTIONS = () => ({
    tabBarButton: renderTabBarButton
})

const TestNavigator = () => {
    return (
        <TabNav.Navigator>
            <TabNav.Screen options={TAB_OPTIONS()} name={'tab1'} component={TestScreen}/>
            <TabNav.Screen options={TAB_OPTIONS()} name={'tab2'} component={TestScreen}/>
        </TabNav.Navigator>
    )
}

const StackNav = createNativeStackNavigator();
const Main = () => {
    return (
        <StackNav.Navigator>
            <StackNav.Screen name={'tabs'} component={TestNavigator}/>
            <StackNav.Screen name={'asd'} component={TestScreen}/>
        </StackNav.Navigator>
    )
}

class App {
  render() {
          return (
              <NavigationContainer>
                  <Main/>
              </NavigationContainer>
          );
  }
}

@okwasniewski
Copy link
Contributor

Here I have a simple tab navigator inside a stack navigator. Whenever I switch tabs I get this re-render:

Hey @constantinescu-vlad,

Why are you passing options as a function? This way every time you are creating a new reference to the returned object. Please replace this:

const TAB_OPTIONS = () => ({
    tabBarButton: renderTabBarButton
})

const TestNavigator = () => {
    return (
        <TabNav.Navigator>
            <TabNav.Screen options={TAB_OPTIONS()} name={'tab1'} component={TestScreen}/>
            <TabNav.Screen options={TAB_OPTIONS()} name={'tab2'} component={TestScreen}/>
        </TabNav.Navigator>
    )
}

with:

const TAB_OPTIONS = {
    tabBarButton: renderTabBarButton
}

const TestNavigator = () => {
    return (
        <TabNav.Navigator>
            <TabNav.Screen options={TAB_OPTIONS} name={'tab1'} component={TestScreen}/>
            <TabNav.Screen options={TAB_OPTIONS} name={'tab2'} component={TestScreen}/>
        </TabNav.Navigator>
    )
}

@constantinescu-vlad
Copy link

Here I have a simple tab navigator inside a stack navigator. Whenever I switch tabs I get this re-render:

Hey @constantinescu-vlad,

Why are you passing options as a function? This way every time you are creating a new reference to the returned object. Please replace this:

const TAB_OPTIONS = () => ({
    tabBarButton: renderTabBarButton
})

const TestNavigator = () => {
    return (
        <TabNav.Navigator>
            <TabNav.Screen options={TAB_OPTIONS()} name={'tab1'} component={TestScreen}/>
            <TabNav.Screen options={TAB_OPTIONS()} name={'tab2'} component={TestScreen}/>
        </TabNav.Navigator>
    )
}

with:

const TAB_OPTIONS = {
    tabBarButton: renderTabBarButton
}

const TestNavigator = () => {
    return (
        <TabNav.Navigator>
            <TabNav.Screen options={TAB_OPTIONS} name={'tab1'} component={TestScreen}/>
            <TabNav.Screen options={TAB_OPTIONS} name={'tab2'} component={TestScreen}/>
        </TabNav.Navigator>
    )
}

okwasniewski hey thanks for the reply. It doesnt matter how I write the tab navigator options. the StaticContainer still re-renders unnecessarily

@okwasniewski
Copy link
Contributor

okwasniewski commented Mar 25, 2023

@constantinescu-vlad I've just checked your comment one more time. StaticContainer is supposed to rerender every time you change a route and it prevents child routes from rerendering. So this is not a bug.

@constantinescu-vlad
Copy link

@okwasniewski ok got it, thank you for your information

@wilmxre
Copy link

wilmxre commented Apr 27, 2023

@constantinescu-vlad hey man, did you manage to solve this issue?

@constantinescu-vlad
Copy link

@wilmxre no, I still get the re-render

@Jamal-ReachFirst
Copy link

Yes, re-render all tab screens when tab is changed

@mahbubshaun
Copy link

I'm also facing same issue!

@Cheizr
Copy link

Cheizr commented Mar 3, 2024

I had a similar issue, when i switch between two tabs for example, every component was re-rendered.

The problem was that I was passing a Contextprovider as a child of NavigationContainer, i level up my ContextProvider and the re-renders stopped

@wilmxre
Copy link

wilmxre commented Mar 6, 2024

yeah, a context provider caused the re-rendering for me too

@Cheizr
Copy link

Cheizr commented Mar 7, 2024

yeah, a context provider caused the re-rendering for me too

Try what i said in my previous comment, that fixed it

@manhhoang02

This comment was marked as resolved.

@FadyBoj
Copy link

FadyBoj commented Jun 16, 2024

I had a similar issue, when i switch between two tabs for example, every component was re-rendered.

The problem was that I was passing a Contextprovider as a child of NavigationContainer, i level up my ContextProvider and the re-renders stopped

Yes this solution worked for me too , thanks

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