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
You have a mistake in the function declaration of
handleAddFriend
. You are saying you expect an object to be passed that has a key calledfriend
. You’re actually passing it an object that is thefriend
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:
To:
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.