How to create pass state value from parent component to child components within stack navigation

Viewed 127

Hey guys I am currently having an issue with passing state values from a parent component for Stack Navigator to child components.

My parent component:

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { View, StyleSheet, FlatList } from 'react-native';
import AppLoading from 'expo-app-loading';
import * as Font from 'expo-font';
import Navigator from './routes/stack.js';

let customFonts = {
  'Jost_400Regular': require('./assets/fonts/Jost_400Regular.ttf'),
  'Jost_600SemiBold': require('./assets/fonts/Jost_600SemiBold.ttf'),

};
    

export default class App extends React.Component {
  state = {
    fontsLoaded: false,
    cardInfo: [],
  };

  async _loadFontsAsync() {
    await Font.loadAsync(customFonts);
    this.setState({ fontsLoaded: true });
    const response = await fetch('https://umamiapp.herokuapp.com/');
    const jsonresponse = await response.json();
    let tempImages = [];

    for (let i = 0; i < jsonresponse.length; i++) {
        tempImages.push(jsonresponse[i]);
    }
     
    this.setState({
      cardInfo : tempImages
    });
  }

  componentDidMount() {
    this._loadFontsAsync();
  }
  renderCards = () => {
    console.log(this.state.cardInfo);
    return (
    <View>
        <Navigator />
    </View>)
  }
  render() {
    if (this.state.fontsLoaded) {
      return (
        <FlatList 
          style={styles.container}
          data={[1]}
          renderItem={this.renderCards}
        />
      );
    } else {
      return <AppLoading />;
    }
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    marginTop: 50
  },
});

My navigation page:

import { createStackNavigator } from 'react-navigation-stack';
import { createAppContainer } from 'react-navigation';
import Cards from '../components/Cards.js';
import CardCommentPage from '../components/CardCommentPage.js';

const screens = {
  Cards: {
    screen: Cards,
  },
  CardCommentPage: {
    screen: CardCommentPage,
  },
};

// home stack navigator screens
const stack = createStackNavigator(screens);

export default createAppContainer(stack);

I want to be able to pass the cardInfo array from the state of the parent component as a prop for the Cards component within the navigation page and got lost looking at the documentation. I was wondering if this was possible. Thank you.

1 Answers

I'm not sure if I understand your question well, but maybe you're trying to passing cardInfo state into your item inside Flatlist right?

If so, here is the problem, the component rendered by renderItem of FlatList are PureComponent which will not update when it props change. During _loadFontsAsync you set fontsLoaded: true which made the FlatList to render but at this time, your cardInfo still empty until your api response and when it does response, then your cardInfo updated, but PureComponent will not take any further props change so it's the cause of your problem.

Here is the solution, luckily, FlatList do provide us a property that will take into consideration for a component should update or not when props change. By passing cardInfo into extraData, your FlatList item should be aware of this props.

<FlatList
   ....
   extraData={this.state.cardInfo}
/>

Here is the documentation FlatList-extraData

Related