javascriptreactjsreact-nativereact-native-tab-view

Issue with passing state as prop to react-native-tab-view?


I'm using react-native-tab-view and rendering two tabs.

I'm calling an api in the parent component, saving it to the parent state and then passing the state saved as prop to the child tabs.

But, I'm only receiving the initial state in the componentDidMount of the child tabs. However, in the render i'm able to receive the updated state from the api.

How can I get the final data in the componentDidMount of the child?

Here is how my parent component:

class Parent extends Component {
  state = {
    index: 0,
    data: [],
    routes: [{ key: 'tab1', title: 'Tab 1' }, { key: 'tab2', title: 'Tab 2' }],
  };

  componentDidMount() {
    this.getData();
  }

  getStudentList = async () => {
    axios
      .get('/api-url')
      .then(function(response) {
        // saving data to state
        this.setState({ data: response.data });
      })
      .catch(function(error) {
        // handle error
        console.log(error);
      });
  };

  renderScene = ({ route }) => {
    switch (route.key) {
      case 'tab1':
        return <Tab1 data={this.state.data} />; // passing data as data prop
      case 'tab2':
        return <Tab1 data={this.state.data} />;
      default:
        return null;
    }
  };

  handleIndexChange = index => {
    this.setState({ index });
  };

  render() {
    return (
      <TabView
        navigationState={this.state}
        renderScene={this.renderScene}
        renderTabBar={props => <TabBar {...props} />}
        onIndexChange={this.handleIndexChange}
      />
    );
  }
}

In my child tab component i'm not receiving the data from the api but the initial empty array.

Child component:

class Tab1 extends React.Component {
  componentDidMount() {
    console.log(this.props.data); // Logs out []
  }

  render() {
    console.log(this.props.data); // gives the api data
    return (
      <SafeAreaView style={styles.container}>
        <Text>Child</Text>
      </SafeAreaView>
    );
  }
}

Solution

  • I don't know this.getData() did what, but I think componentDidMount get initial data, because you used setState. setState is Asynchronous method, so states change after componentDidMount get states.

    How about using componentDidUpdate? I think it will work because it start after rendering and updating.

    I hope it helps.