0

This is my code. I don't know why but the error is in the "FriendList" Component

I tired goggling and asking chat gpt but it doesn't work. Thanks.

/* eslint-disable react/no-unescaped-entities */
/* eslint-disable react/prop-types */
import { useState } from "react";

const initialFriends = [
    {
        id: 118836,
        name: "Clark",
        image: "https://i.pravatar.cc/48?u=118836",
        balance: -7,
    },
    {
        id: 933372,
        name: "Sarah",
        image: "https://i.pravatar.cc/48?u=933372",
        balance: 20,
    },
    {
        id: 499476,
        name: "Anthony",
        image: "https://i.pravatar.cc/48?u=499476",
        balance: 0,
    },
];

const App = () => {
    const [showAddFriend, setShowAddFriend] = useState(false);
    const [friends, setFriends] = useState(initialFriends);
    const handleShowAddFriend = () => {
        setShowAddFriend((show) => !show);
    };
    const handleAddFriend = ({ friend }) => {
        setFriends((friends) => [...friends, friend]);
    };

    return (
        <div className="app">
            <div className="sidebar">
                <FriendList friends={friends} />
                {showAddFriend && <FormAddFriend onAddFriend={handleAddFriend} />}
                <Button onClick={handleShowAddFriend}>
                    {showAddFriend ? "Close" : "Add friend"}
                </Button>
            </div>
            <FormSplitBill />
        </div>
    );
};

const Button = ({ children, onClick }) => {
    return (
        <button onClick={onClick} className="button">
            {children}
        </button>
    );
};

const FriendList = ({ friends }) => {
    return (
        <ul>
            {friends.map((friend) => (
                <Friend friend={friend} key={friend.id} />
            ))}
        </ul>
    );
};

const Friend = ({ friend }) => {
    return (
        <li>
            <img src={friend.image} alt={friend.name} />
            <h3>{friend.name}</h3>
            {friend.balance < 0 ? (
                <p className="red">
                    You owe {friend.name} {Math.abs(friend.balance)}$
                </p>
            ) : friend.balance === 0 ? (
                <p>You and {friend.name} are even</p>
            ) : (
                <p className="green">
                    {friend.name} owes you {friend.balance}$
                </p>
            )}
            <Button>Select</Button>
        </li>
    );
};

const FormAddFriend = ({ onAddFriend }) => {
    const [name, setName] = useState("");
    const [image, setImage] = useState("https://i.pravatar.cc/48");

    const handleSubmit = (e) => {
        e.preventDefault();
        if (!name || !image) return;
        const id = crypto.randomUUID();
        const newFriend = {
            id,
            name,
            image: `${image}?=${id}`,
            balance: 0,
        };
        onAddFriend(newFriend);
        setName("");
        setImage("https://i.pravatar.cc/48");
    };

    return (
        <form className="form-add-friend" onSubmit={handleSubmit}>
            <label>Friend name</label>
            <input
                type="text"
                value={name}
                onChange={(e) => setName(e.target.value)}
            />
            <label>Image URL</label>
            <input
                value={image}
                onChange={(e) => setImage(e.target.value)}
                type="text"
            />
            <Button>Add</Button>
        </form>
    );
};

const FormSplitBill = () => {
    return (
        <form className="form-split-bill">
            <h2>Split a bill with X</h2>
            <label>💲 Bill value</label>
            <input type="text" />
            <label>💵 Your expense</label>
            <input type="text" />
            <label>👨🏿‍🤝‍👨🏾 X's expense</label>
            <input type="text" />
            <label>😅 Who is paying the bill</label>
            <select>
                <option value="user">You</option>
                <option value="friend">X</option>
            </select>
            <Button>Split bill</Button>
        </form>
    );
};

export default App;

I am learning from a Udemy course. Here's the error message from the console. App.jsx:62 Uncaught TypeError: Cannot read properties of undefined (reading 'id') at App.jsx:62:45 at Array.map () at FriendList (App.jsx:61:16) console.js:213 The above error occurred in the component: your text at FriendList (http://localhost:5173/src/App.jsx?t=1705498582948:92:23) at div at div at App (http://localhost:5173/src/App.jsx?t=1705498582948:41:45)

2 Answers 2

1

You're passing the onAddFriend function as a prop to FormAddFriend. In FormAddFriend, you are trying to call onAddFriend as a function with an argument, but you have defined it as an object destructuring parameter.

Pass the onAddFriend function directly without wrapping it inside an object.

const handleAddFriend = (friend) => {
    setFriends((friends) => [...friends, friend]);
  };
Sign up to request clarification or add additional context in comments.

Comments

0

You have a mistake in the function declaration of handleAddFriend. You are saying you expect an object to be passed that has a key called friend. You're actually passing it an object that is the friend object. So destructuring is wrong here. By destructuring a property that doesn't exist, it's undefined when you add it to the array. The result is state that looks something like [friend, friend, friend, undefined].

To correct, simply change from:

const handleAddFriend = ({ friend }) => {
  setFriends((friends) => [...friends, friend]);
};

To:

const handleAddFriend = (friend) => {
  setFriends((friends) => [...friends, friend]);
};

Comments

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.