0

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

3
  • 1
    Why Object.keys() for an array? Commented Mar 23, 2022 at 10:13
  • 1
    And you need to do API call in the useEffect hook and store the response of the API in the useState Commented Mar 23, 2022 at 10:14
  • no need to use Object.keys, use Object.values instead Commented Mar 23, 2022 at 11:54

1 Answer 1

1

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,
    }
  });
Sign up to request clarification or add additional context in comments.

7 Comments

thanks, that seems logical, but now it says: TypeError: can't convert undefined to object
Can you console.log(data) right before the return statement of the view and show it to me?
It says undefined.
Are you sure that your implementation of useEffect is the exact same as in the current answer?
yes definetely.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.