React-native-tab-view: renderScene is called too many times

Created on 20 Dec 2019  路  8Comments  路  Source: satya164/react-native-tab-view

Current behaviour

I'm trying to understand the reasoning behind the following behavior. Is this a bug or intended behavior?
As an example, there are two tabs total -
When moving between tabs with the tab bar, renderScene is called once per tab, 2 times total. I don't quite get why it happens at all? It was already called before, so why it is needed to be called again?

When moving between tabs with a gesture, renderScene is called twice per tab. Tab A, then Tab B, then Tab A again, then Tab B.

Expected behaviour

renderScene should not be called for every tab change, but it certainly shouldn't be called twice per tab change with a gesture.

Code sample

What have you tried

The components that are returned from renderScene are using React.memo and are not actually being rendered, so this is not actually expensive. I'm just trying to understand the reasoning behind this behavior and if it's a bug.

Your Environment

| software | version
| ---------------------------- | -------
| ios or android | ios
| react-native | 0.61.4
| react-native-tab-view | 2.11.0
| react-native-gesture-handler | 1.5.2
| react-native-reanimated | 1.4.0
| node | 12.13.1
| npm or yarn | npm

bug

All 8 comments

same problem ,

same problem ,

i solved this problem just now.maybe this way can help
renderScene={SceneMap(this.renderScenes)}
this prop should be a const parameter,'this.renderScenes' should be const
this.renderScenes = this.renderScenes();
this way had solved my problem..by the way dont put the renderScenes in render method

@shadow-boy what does renderScenes look like? What's the return value?

I'm trying to understand the reasoning behind the following behavior. Is this a bug or intended behavior?
As an example, there are two tabs total -
When moving between tabs with the tab bar, renderScene is called once per tab, 2 times total. I don't quite get why it happens at all? It was already called before, so why it is needed to be called again?

Imagine this code:

function MyComponent() {
  const items = ['a', 'b'];

  return (
    <View>
      {items.map(item => {
        console.log('called');

        return <Text>{item}</Text>;
      )}
    </View>
  );
}

Whenever this component re-renders, your console.log will be called multiple times (twice here with the 2 items). Your screens aren't any different. Every render, we need to re-render children as well, otherwise things will be out of date (e.g. if you're using parent state inside renderScene and the state changes). It's called 2 times per update because you have 2 items, like the map here. If we internally update state in the library, it'll cause a re-render.

This is not a bug. This is how React works. The docs specifically tell you this https://github.com/react-native-community/react-native-tab-view#avoid-unnecessary-re-renders

@satya164: When moving between tabs with a gesture, renderScene is called twice per tab. Why is that?

Why does it matter?

@satya164 I memoized my tab components, so it doesn't, but I still wonder why does it call renderScene twice per tab. seems wasteful?

@satya164 does this mean if I'm using functional component with react-native-tab-view, then it's inevitable to get every scene rerendered whenever I switch a tab?

the code pattern is like this:

const Component = (props) => {
  const [index, setIndex] = useState(0)
  const [routes] = React.useState([
    { key: 'first', title: 'First' },
    { key: 'second', title: 'Second' },
  ]);

  const renderScene = ({ route }) => {
    const data = datas[route.key]
    return <AnotherComponent data={data} >
  }

  return (
    <TabView
      navigationState={{ index, routes }}
      renderScene={renderScene}
      onIndexChange={setIndex}
      initialLayout={initialLayout}
    />
  );
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

lubomyr picture lubomyr  路  3Comments

glennvgastel picture glennvgastel  路  3Comments

jouderianjr picture jouderianjr  路  3Comments

ashusdn picture ashusdn  路  4Comments

KingAmo picture KingAmo  路  3Comments