简体   繁体   中英

React native flat list not rendering items

I hope you're doing okay

I'm experiencing something weird with my react-native project, The FlatList items in some of the pages aren't displayed, even though I can see them when I console.log(json.items).

Earlier today, everything worked fine. all the pages displayed their lists as they should on my device. then I started working on a new search page on snack & I added status bar, I tested and it worked on snack before adding the new code and creating the new files in my app.

The issue I'm having now is, the list on the first page is displayed, subsequent pages after that do not show list items. including the new search page that works on snack

I'll go ahead and post my code now, the first set is for the page whose listitems are displayed correctly:

App.js

class ProfileActivity extends Component
{

  // Setting up profile activity title.
   static navigationOptions = ({ navigation }) =>
   {
     return {
      title: 'Home',
      headerStyle : {
        backgroundColor: '#00b47a',
        elevation: 0
      },
      headerTitleStyle: {
        color: 'white'
      },
      cardStyle: { backgroundColor: '#fff' },
      headerLeft: null,
      headerRight: (
        <View style={{ alignSelf: 'center', alignItems: 'center', display: 'flex', flexDirection: 'row', justifyContent: 'space-evenly'}}>
        <Icon containerStyle={{ paddingRight: 10 }}
        color='#fff' onPress={()=> navigation.getParam('openBottomSheet')()}
        name="menu" />
        <Icon containerStyle={{ paddingRight: 15 }}
        color='#fff' onPress={()=> navigation.getParam('openSearchPage')()}
        name="search" /></View>
      )
     }
   };

   constructor () {
    super()
    this.state = { toggled: false }
  }

  componentDidMount() {
    this.props.navigation.setParams({ openBottomSheet: this.onOpenBottomSheet });
    this.props.navigation.setParams({ openSearchPage: this.onOpenSearchPage });
  }

  onOpenBottomSheet = ()  => {
     this.Standard.open();
  }
  onOpenSearchPage = ()  => {
    this.props.navigation.navigate('sixth');
 }

  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center'}}>
        
      <StatusBar
      animated={true}
      backgroundColor="#00b47a"
      barStyle={'light-content'}
      showHideTransition={'slide'}
      hidden={false} />
         <MarketList navigation={this.props.navigation} />
         <RBSheet
           ref={ref => {
             this.Standard = ref;
           }}        
         >
...
         </RBSheet>
         </View>
    );
  }
}            
 

Market.js

export default class MarketList extends React.Component {
  constructor(props) {
 
    super(props)
 
    this.state = {
      items: '',
    };
    this.animateList = new Animated.Value(0);
}

componentDidMount() {
  Animated.timing(this.animateList, {
    toValue: 1,
    duration: 500,
  }).start();
}
  render() {
    const rowStyles = [
        styles.itemList,
        { opacity: this.animateList },
        {
          transform: [
            { scale: this.animateList },
          ],
        },
      ];

      
    fetch('https://mvmarket.xyz/nativeuserapp/home.php')
    .then((response) => response.json())
    .then((json) => {
      this.setState({
        items: json.items,
      })
    })
    .catch((error) => {
      console.error(error);
    });
    return (
      <View style={styles.container}>
        <FlatList
          data={this.state.items}
          renderItem={({item}) => <TouchableOpacity onPress={()=>this.props.navigation.navigate("fourth",{market:item.name})}><Animated.View style={rowStyles}><View style={styles.item}><Text style={styles.market}>{item.name}</Text><Text style={styles.location}>{item.Location}</Text></View><View style={styles.go}><Icon name="arrow-right" color="#00b47a" /></View></Animated.View></TouchableOpacity>}
        />
      </View>
    );
  }
}

This next set is for one of the pages that don't show list items

App.js

class ProductsActivity extends Component {
  static navigationOptions =
  {
     title: 'Products',
     headerStyle : {
       backgroundColor: '#00b47a',
       elevation: 0
     },
    cardStyle: { backgroundColor: '#fff' },
     headerTitleStyle: {
       color: 'white'
     },
  };

  render() {

    return(
      <View>
      <StatusBar
      animated={true}
      backgroundColor="#00b47a"
      barStyle={'light-content'}
      showHideTransition={'slide'}
      hidden={false} />
      <ProductsList navigation={this.props.navigation} />
      </View>
    );
  }
}

Products.js

export default class ProductsList extends React.Component {
  constructor(props) {
 
    super(props)
 
    this.state = {
      items: '',
    };
  }
  
  render() {
    fetch('https://mvmarket.xyz/nativeuserapp/products.php')
    .then((response) => response.json())
    .then((json) => {
      this.setState({
        items: json.items,
      })
    }).catch((error) => {
      console.error(error);
      console.log(error);
    });
    return (
      <View style={styles.container}>
        <FlatList
          data={this.state.items}
          renderItem={({item}) => <TouchableOpacity onPress={()=>this.props.navigation.navigate("fifth",{market: this.props.navigation.state.params.market, type:item.type})} style={styles.itemList}><View style={styles.item}><Text style={styles.market}>{item.type}</Text></View><View style={styles.go}><Icon name="arrow-right" color="#00b47a" /></View></TouchableOpacity>}
        />
      </View>
    );
  }
}

I'm leaving the URL there so you can confirm yourself that the data is actually fetched. Its driving me crazy, been on it for like 4 hrs.

Thank you

I think you don't really understand lifecycle methods of a React Component. It's important to understand those concepts before jumping into code. You can check here

When you put your fetch call in render , and on then you do a setState() you are making this infinitely. This happens because you are always providing new values to items .

The ideal is to have a model layer to handle those type of calls, but this is an architecture thing, to be less complex, you can use Container/Presentation pattern.

In the Container/Presentation pattern, you have a ContainerComponent which is responsible to do requests, handle callbacks, and provide data to the Presentation component, which would be responsible to just render things.

If you don't want to use this pattern, at least put this fetch call in componentDidMount method.

Thank you all for your suggestions, duly noted and appreciated.

@Witalo-Benicio @Andris-laduzans @Drew-reese

I've fixed it, by changing

class SearchMarketActivity extends Component {
  static navigationOptions = {
    headerShown: false, 
    cardStyle: {
      backgroundColor: 'white'
    }
  }

  render() {
    return(
       <View>
        <StatusBar
        animated={true}
        backgroundColor="#585858"
        barStyle={'light-content'}
        showHideTransition={'slide'}
        hidden={false} />

        <SearchMarket navigation={this.props.navigation} />
</View>
    )
  }
}

to

class SearchMarketActivity extends Component {
  static navigationOptions = {
    headerShown: false, 
    cardStyle: {
      backgroundColor: 'white'
    }
  }

  render() {
    return(
        <SearchMarket navigation={this.props.navigation} />
    )
  }
}

After, I added the StatusBar to the <SearchMarket /> component being imported

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM