Search code examples
reactjsarraystypescriptreact-propsreact-typescript

React.Js - Typescript how to pass an array of Objects as props?


everyone.

So I am learning TypeScript with React.Js and I have come to a problem.

I have a "page" that has an array of objects that have further information about each user

const USERS = [
        {name: 'Nicole', id: 1, placeCount: 10, places: 'place 1', image: 'image source'},
        {name: 'Sarah', id: 2, placeCount: 20, places: 'place 3', image: 'asdasd'}
    ];

Now, I have a User page that renders list of all users, and this list is a component that is made out of UsersListItem component, now this component renders all data from each object inside the USERS array. I know how to pass one object from USERS array, but I want to send whole array with all objects

So question is how can I pass the USERS array into UsersList ?

This is my structure

This is my /users page

import UsersList from '../components/UsersList';


function User() {
    const USERS = [
        {name: 'Nicole', id: 1, placeCount: 10, places: 'place 1', image: 'image source'},
        {name: 'Sarah', id: 2, placeCount: 20, places: 'place 3', image: 'asdasd'}
    ];


    return (
  
        <UsersList  
            user={USERS[0].name} 
            id={USERS[0].id} 
            image={USERS[0].image} 
            placeName={USERS[0].places} 
            placeCount={USERS[0].placeCount}/>
     
      )
}

export default User

This is my UsersList component

import UsersListProps from './props/props_UserItem';
import UserIListtem from './UserIListtem';



const UsersList = ( props : UsersListProps) =>{

    const {user, id, image, placeCount, placeName} = props

    if(props === null){
        return(
            <div>
                <h1>No users found</h1>
            </div>
        );
    }

    return(
        <ul>
            {
                <UserIListtem 
                    user={user} 
                    id={id} 
                    image={image} 
                    placeName={placeName} 
                    placeCount={placeCount}/> 
            }
        </ul>
    );
  
}

and this is my UsersListItem component

import UsersListProps from './props/props_UserItem';

const UserIListtem = (props: UsersListProps) => {
    const {user, id, image, placeCount, placeName} = props;
  return (
    <li>
    <div>

        <div>
            <img src={image} alt={placeName}/>
        </div>
        <div>{id}
            <h2>{user}</h2>
            <h3>{placeCount}</h3>
        </div>
    </div>

</li>
  )
}

export default UserIListtem

And this is my UsersListProps props that I had put into seperate file called props_UserItem.tsx

interface UsersListProps {
    user: string,
    id: number,
    image: string,
    placeCount: number,
    placeName: string

}

export default UsersListProps

Solution

  • You can simply return this in the User component:

    return (
     <UsersList users={USERS} />
    )
    

    Then the UsersList component will become:

    const UsersList = ( { users } : UsersListProps) => {
     if(!users?.length){
       return(
         <div>
           <h1>No users found</h1>
         </div>
       );
     }
     return(
      <ul>
       {users.map(({ id, name, image, places, placeCount }) => (
         <UserIListtem
          key={id} 
          name={name} 
          id={id} 
          image={image} 
          places={places} 
          placeCount={placeCount}/> 
       ))}
      </ul>
     );
    }
    

    And the UserIListtem component:

    const UserIListtem = ({ name: user, id, image, placeCount, places: placeName }: User) => {
     return (
      <li>
       <div>
        <div>
         <img src={image} alt={placeName}/>
        </div>
        <div>{id}
         <h2>{user}</h2>
         <h3>{placeCount}</h3>
         </div>
       </div>
      </li>
     )
    }
    

    Remember to also change the UsersListProps interface to:

    export interface UsersListProps {
     users: User[];
    }
    
    export interface User {
     id: number;
     name: string;
     image: string;
     placeCount: number;
     places: string;
    }