Leon_Rickert
Leon_Rickert

Reputation: 31

React Native Client cannot render JSON data from api call

I am currently trying to make a react native app that shall fetch an api and then render that data. However it does not work and I do not know what I am doing wrong. My API returns an Object that is correctly logged out in my console. But in my actual react native app I only get "undefined" displayed if I try to render it. Apart from that my console says the following even tho i specify a unique key prop in my component:

"Warning: Each child in a list should have a unique "key" prop."

Here is my code:

export default function MyComponent() {

  const myData = fetch('(Right URL from API stands here)', {
    method: 'GET'
  })
  .then(res => res.json())
  .then(data => console.log(data));

    return (
      <View style={styles.container}>
        {
          Object.keys(myData).map(data => {
            return (
              <View key={data.id}>
                  <Text>{"Data: " + data.message}</Text>
              </View>
                
            )
          })
        }
      </View>
    );
  }

  const styles = StyleSheet.create({
    container: {
      flex: 1,
      alignItems: "center",
      marginTop: 48,
    }
  });

    

Here is my console logging out an object after fetching data:

Array [
  Object {
    "message": "This is a message",
    "username": "leon42",
    "id": 1,
    "timing": "2022-01-01T12:00:00.000Z",
  },
  Object {
    "message": "This is a message",
    "username": "henry42",
    "id": 2,
    "timing": "2022-01-01T12:00:00.000Z",
  },
  Object {
    "message": "This is a message",
    "username": "pauli42",
    "id": 3,
    "timing": "2022-01-01T12:00:00.000Z",
  },
]

My Component then looks like this on my phone: enter image description here

Upvotes: 0

Views: 450

Answers (1)

David Scholz
David Scholz

Reputation: 9866

Your fetch is async, thus in your first render cycle the data is undefined. The reason why it is defined in your log message is because you are using a then chain. However, since the render cycle is already finished, the screen won't react on the updated information.

Create a state and update the state once the API call returns its data. The state change will cause a rerendering.

export default function MyComponent() {

  const [data, setData] = useState()

  React.useEffect(() => {
     const fetchData = async () => {
        
         const d = await fetch('(Right URL from API stands here)', {
                method: 'GET'
         })
        setData(d)
     }
     
     fetchData()
  }, [])

    return (
      <View style={styles.container}>
        {
          Object.keys(data).map(item => {
            return (
              <View key={item.id}>
                  <Text>{"Data: " + item.message}</Text>
              </View>
                
            )
          })
        }
      </View>
    );
  }

  const styles = StyleSheet.create({
    container: {
      flex: 1,
      alignItems: "center",
      marginTop: 48,
    }
  });

Upvotes: 1

Related Questions