rizji
rizji

Reputation: 413

Can't render data from API being passed down as props (ReactJS)

I'm really stuck in trying to render some data being passed down as props. I'll include some code and definitions below, but if you feel that I need to include some further code snippets, please let me know (I'm really struggling to find what's causing the error, so I may have missed out the causal issue!).

I first take data from an API which is then used to populate a UserList component via useState (setUsers(data):

useEffect(() => {
  async function getUserList() {
    setLoading(true);
    try {
      const url =
        "API URL";
      const response = await fetch(url);
      const data = await response.json();
      setUsers(data);
    } catch (error) {
      throw new Error("User list unavailable");
    }
    setLoading(false);
  }

  getUserList();
}, []);

If a user is clicked in the UserList, this changes the selectedUser state of the parent Home component to be the specific user's unique_ID via:

onClick={() => setSelectedUser(unique_ID)}

If the selectedUser changes, the Home component also does a more updated data fetch from the API to get all information relevant to the specific user via their unique_ID:

  useEffect(() => {
    async function getSelectedUserData() {
      try {
        const url = `API URL/${selectedUser}`;
        const response = await fetch(url);
        const data = await response.json();
        setSelectedUserData(data);
      } catch (error) {
        throw new Error("User data unavailable");
      }
    }

    getSelectedUserData();
  }, [selectedUser]);

The specific user data is then passed down as props to a child UserInformation component:

<UserInformation selectedUser={selectedUser} selectedUserData={selectedUserData} />

At this point, I can see all the data being passed around correctly in the browser React Developer Tools.

The UserInformation component then gets the data passed via props:

import React, { useEffect, useState } from "react";

function UserInformation({ selectedUser, selectedUserData }) {
  const [currentUser, setCurrentUser] = useState({ selectedUserData });

  useEffect(() => {
    setCurrentUser({ selectedUserData });
  }, [selectedUser, selectedUserData]);

  return (
    <div>
      <p>{selectedUserData.User_Firstname}</p>
      <p>{currentUser.User_Firstname}</p>
    </div>
  );
}

export default UserInformation;

And here is where I get stuck - I can't seem to render any of the data I pass down as props to the UserInformation component, even though I've tried a few different methods (hence the <p>{selectedUserData.User_Firstname}</p> and <p>{currentUser.User_Firstname}</p> to demonstrate).

I'd really appreciate any help you can give me with this - I must be making an error somewhere!

Thanks so much, and sorry for the super long post!

Upvotes: 0

Views: 184

Answers (2)

rizji
rizji

Reputation: 413

I managed to solve this (thanks to the help of Mohamed and Antonio above, as well as the reactiflux community).

import React from "react";

function UserInformation({ selectedUserData }) {
  const currentUserRender = selectedUserData.map(
    ({ User_Firstname, User_Lastname }) => (
      <div key={unique_ID}>
        <p>{User_Firstname}</p>
      </div>
    )
  );

  return (
    <div>
      {selectedUserData ? currentUserRender : null}
    </div>
  );
}

export default UserInformation;

As selectedUserData was returning an array instead of an object, I needed to map the data rather than call it with an object method such as {selectedUserData.User_Firstname}.

  const currentUserRender = selectedUserData.map(
    ({ User_Firstname, User_Lastname }) => (
      <div key={unique_ID}>
        <p>{User_Firstname}</p>
      </div>
    )
  );

The above snippet maps the selected data properties found inside selectedUserData ({ User_Firstname, User_Lastname }), with the whole map being called in the return via {selectedUserData ? currentUserRender : null}.

Hopefully my explanation of the above solution is clear for anyone reading, and a big thanks again to Mohamed and Antonio (as well as a few others in the reactiflux Discord community) for helping!

Upvotes: 1

Mohamed Wagih
Mohamed Wagih

Reputation: 1456

You're trying to set the current user to an object with key "selectedUserData".

So if you want to access it you've to access it by this key name so change this line currentUser.User_Firstname to currentUser.selectedUserData.User_Firstname

Upvotes: 0

Related Questions