Reputation: 1356
Doing my project with NextJS I encounter a part where I made a component called
app_buttonGray
and it looks like this:
// /components/app_buttonGray.js
export default function AppButtonGray({ size, children }){
return(
<button className={`flex w-${size ? size : "36"} mt-2 p-1 rounded-md bg-gray-500 hover:bg-gray-800 shadow-lg justify-center`}>
{children}
</button>
)
}
Later in my page I want to create multiple buttons but each of them have different purposes
So I want to implement onClick
like this:
<AppButtonGray size="48" onClick={ () => alert(1)}>New project</AppButtonGray>
<AppButtonGray size="48" onClick={ () => alert(2)}>Open project</AppButtonGray>
But that doesn't seem to work...
After multiple intents I come up with this modification that made it work:
// /components/app_buttonGray.js
export default function AppButtonGray({ size, onClick, children }){
return(
<button onClick={onClick} className={`flex w-${size ? size : "36"} mt-2 p-1 rounded-md bg-gray-500 hover:bg-gray-800 shadow-lg justify-center`}>
{children}
</button>
)
}
So I had to pass by parameter the onClick
and then call it inside the component...
Is that the right way to make this work? If not then what's the right way? Thanks
Upvotes: 3
Views: 12136
Reputation: 29
You can simply use onClick like you used it:
type Props = {
children: React.ReactNode;
onClick?: (e: any) => void;
};
const Button: React.FC<Props> = ({ children, onClick }) => {
return (
<button onClick={onClick}>
{children}
</button>
);
};
export default Button;
Now in your parent, you can simply parse a function. But make sure you use "use client":
"use client"
import Button from "./Button";
<Button onClick={() => {alert("test");}}>Click</Button>
Upvotes: 0
Reputation: 1927
Yes this is the right way to accomplish what you're trying to do. In React you always have to pass any custom props down to the elements you are returning if you want them to be applied.
One alternative way to accomplish this however is by using the rest syntax (...
) to grab all of the remaining props passed to your component and spreading them onto the child component.
// Get the remaining props
export default function AppButtonGray({ size, children, ...props }) {
return (
<button
className={`flex w-${
size || "36"
} mt-2 p-1 rounded-md bg-gray-500 hover:bg-gray-800 shadow-lg justify-center`}
{...props}
>
{children}
</button>
);
}
This is an effective way to pass any props you'd like to your child component but it can be worse for readability when trying to understand the component. This is why some ESLint configs disallow this strategy (you can read more about that here).
Personally I think you should stick to the way you made it in most cases, you'll thank yourself in the long run when trying to understand the code you wrote.
Upvotes: 3