If we look at the following code, we can see that we’re trying to assign a boolean to the const “isSelected” — We’re saying that if the selectedFriend.id is equal to friend.id, then set “isSelected” to true, else set to false…..
function Friend({ friend, onSelectFriend, selectedFriend }) {
const isSelected = selectedFriend.id === friend.id;
return (
<li className={isSelected ? "selected" : ""}>
<img src={friend.image} alt={friend.name} />
<h3>{friend.name}</h3>
{/* conditional logic goes here */}
{friend.balance < 0 && (
<p className="red">
You owe {friend.name} ${Math.abs(friend.balance)}
</p>
)}
{friend.balance > 0 && (
<p className="green">
{friend.name} Owes you ${friend.balance}
</p>
)}
{friend.balance === 0 && (
<p className="">You and {friend.name} are all square</p>
)}
<Button onClick={() => onSelectFriend(friend)}>
{isSelected ? "Close" : "Select"}
</Button>
</li>
);
}
We may encounter an issue with this if selectedFriend is initially set to null
when comparing null
or undefined
to other values using comparison operators like ===
, they do not strictly equal false
. For example:
null === false; // false
undefined === false; // false
null === undefined; // false
When you try to access a property of null or undefined, it will result in a runtime error (TypeError) rather than evaluating to false:
Uncaught TypeError: Cannot read properties of null (reading 'id')
at Friend (App.js:91:1)
In the example above, where try to directly use it in a comparison like selectedFriend.id === friend.id, it will trigger a TypeError because you’re trying to access the id property of null.
To fix this we should either explicitly check if selectedFriend is truthy before accessing its properties. For example:
const isSelected = selectedFriend && selectedFriend.id === friend.id;
In this case, if the selectFriend object doesn’t exist, then it immediately evaluates to false and therefore isSelected will be false.
Another option, is to use the optional chaining operator (?.
)
It allows you to safely access properties of an object without causing errors if the object (or any intermediate property) is null or undefined.
For example:
const isSelected = selectedFriend?.id === friend.id;
- If
selectedFriend
is null or undefined,isSelected
will be undefined. - If
selectedFriend
has anid
property, thenisSelected
will betrue
orfalse
based on the comparison withfriend.id
.
Using optional chaining in this context is a cleaner and more concise way to handle potential null values compared to manually adding explicit checks. It’s especially useful when dealing with nested properties or when you need to access several properties of an object, as it can simplify your code and make it more readable.