RN - Map directly from state syntax

Viewed 44

I'm trying to map an array from state - but confused re the correct syntax - can anyone please advise where i'm going wrong:

This is what I have at the mo:

      newsStorys = () => {
    return (
      {this.state.newsFeed.map((a) => {

        <View style={ModalStyles.newsArticle}>
          <Text style={ModalStyles.newsDate}>{a.date}</Text>
          <Text style={ModalStyles.newsTitle}>{a.title}</Text>
          <Text style={ModalStyles.newsDesc}>
          {a.story}
          </Text>
        </View>

    }
  }
    );
  };
3 Answers

I'm not sure if that is the whole code of your component, but I can see three things.

  1. If newsFeed is not initialized when component first render (let's say it is undefined yet), then newsFeed.map()will throw an exception.
  2. You are not returning anything from map call. you should write something like this:
     newsStorys = () => {
      if (!this.state.newsFeed) return null;
      return this.state.newsFeed.map((a) => ({ // <--- note the parentheses here, you don't have it
          <View style={ModalStyles.newsArticle}>
            <Text style={ModalStyles.newsDate}>{a.date}</Text>
            <Text style={ModalStyles.newsTitle}>{a.title}</Text>
            <Text style={ModalStyles.newsDesc}>
              {a.story}
            </Text>
          </View>
       });
     );
   };

If you want to avoid the parentheses, then you need to explicitly return something, like this:

    this.state.newsFeed.map((a) => {
       return (
          <View style={ModalStyles.newsArticle}>
            <Text style={ModalStyles.newsDate}>{a.date}</Text>
            <Text style={ModalStyles.newsTitle}>{a.title}</Text>
            <Text style={ModalStyles.newsDesc}>
              {a.story}
            </Text>
          </View>
       );
    });

It is possible that you need an extra view to wrap the list of views returned by map.

  1. Also you need to provide a unique key to each view, so React can keep track on them.
   <View style={ModalStyles.newsArticle} key={'nome unique value'}>
     ...
   </View>

Finally I think it would be better using a FlatList instead of map.

Cheers!

Had a play and a good dig around the web and found the syntax answer: (Thanks to Bruno for the Key and pointers).

newsStorys = () => {
   
    return this.state.newsFeed.map((value, index) => {
      return (
        <View style={ModalStyles.newsArticle} key={index}>
          <Text style={ModalStyles.newsDate}>{value.date}</Text>
          <Text style={ModalStyles.newsTitle}>{value.title}</Text>
          <Text style={ModalStyles.newsDesc}>{value.story}</Text>
        </View>
      );
    });
  };

Try this

newsStorys = () => (
    this.state.newsFeed.map(({ date, story, title }, index) =>
        <View key={`news-${index}`} style={ModalStyles.newsArticle}>
            <Text style={ModalStyles.newsDate}>{date}</Text>
            <Text style={ModalStyles.newsTitle}>{title}</Text>
            <Text style={ModalStyles.newsDesc}>{story}</Text>
        </View>
    ));
Related