I ruined my React components by using optional props
SeongKuk Han
Posted on December 20, 2022
I ruined my React components by using optional props
When I made components, I was trying to make components as flexible as they could using optional parameters. But I found out that it was absolutely wrong.
There were too many options and I wasn't sure what I was going to use to make the component work properly.
I also used unexpected default values a lot. It makes plenty of unnecessary defensive code and I couldn't expect what default values it has.
I will show you some examples that are similar to the mistakes that I made.
Let's say, there is a Button component like below.
import { ReactNode } from 'react';
type ButtonType = 'primary' | 'secondary';
interface ButtonProps {
children?: ReactNode | string;
onClick?: VoidFunction;
type?: ButtonType;
}
const Button = ({ children, onClick, type = 'primary' }: ButtonProps) => {
const bgColor = type === 'primary' ? 'red' : 'blue';
return (
<button style={{ backgroundColor: bgColor }} onClick={onClick}>
{children}
</button>
);
};
export default Button;
Let's see if the optional props are used properly.
-
children
,onClick
: All we know button can be used without text and click event. -
type
: There are two optionsprimary
andsecondary
. We can expect from the name thatprimary
would be used if we don't pass the prop.
import { ReactNode } from 'react';
type ColorButtonColor = 'red' | 'blue';
interface ColorButtonProps {
children?: ReactNode | string;
onClick?: VoidFunction;
color?: ColorButtonColor;
}
const ColorButton = ({
children,
onClick,
color = 'red',
}: ColorButtonProps) => {
return (
<button style={{ backgroundColor: color }} onClick={onClick}>
{children}
</button>
);
};
export default ColorButton;
This button has the color
prop instead of type
.
color
has red
as a default value.
The button might've had the default value for a purpose. For example, red
might've been the most used.
But no one can expect that. In this case, it would be good that color
does not have a default value.
Here is another example.
interface ListProps {
items?: string[];
}
const List = ({ items = [] }: ListProps) => {
return (
<ul>
{items.map((item, itemIdx) => (
<li key={itemIdx}>{item}</li>
))}
</ul>
);
};
export default List;
We can know List
is a general-purposed component.
<List />
You render it and If there is nothing shown, you would know if you forget passing a prop.
Look at another list component.
type UserListItem = {
nickname: string;
intro: string;
};
interface UserListProps {
users?: UserListItem[];
}
const UserList = ({ users = [] }: UserListProps) => {
return (
<ul>
{users.map((user, userIdx) => (
<li key={userIdx}>{`${user.nickname} | ${user.intro}`}</li>
))}
</ul>
);
};
export default UserList;
It's the same as the previous one without the type of item.
<UserList />
If it doesn't have an error, can you know what it is wrong out of the box?
Someone may think UserList
has a business logic and it displays the user list itself.
But it needs the prop users
to display the user list.
If users
is not optional, you must be able to know what is wrong and it would be going to save you time.
When it comes to function properties, it's also the same.
interface NavbarProps {
onSetting: VoidFunction;
onProfile: VoidFunction;
onHome: VoidFunction;
}
const CornerNavbar = ({
onSetting,
onProfile,
onHome,
}: NavbarProps) => {
return (
<ul>
<li onClick={onSetting}>Setting</li>
<li onClick={onProfile}>Profile</li>
<li onClick={onHome}>Home</li>
</ul>
);
};
export default CornerNavbar;
CornerNavbar
has function properties and without these functions, the component wouldn't work as intended. You shouldn't make them optional.
If you defer to implementing some properties, you can use comments and temporary functions.
We can use HTML tags without passing event functions like onClick
, onLoad
, onMouseDown
. I think the fact was confusing me.
Conclusion
These might be considered beginner mistakes and some of you might have your rules to cover this situation other than what I explained.
Although I have been using typescript
, I was getting rid of an advantage of it myself. My opinion that I said in this post could be wrong though, I have learned from it that it is important to keep thinking about what I am used to.
I hope you found something useful in my article.
Happy Coding!
Posted on December 20, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.