I built this toy problem to replicate an issue I am facing in a larger app. Why does handleClick not fire when the button is clicked?
const Button = () => <button type="button">Click me</button>;
export const App = () => {
const handleClick = () => {
console.log("clicked");
};
return <Button onClick={handleClick} />;
};
>Solution :
You pass onClick={handleClick} as a property to Button but the Button component does not use the property.
const Button = () ... // ⚠️ no onClick property used
You can fix this by responding to the onClick property –
const Button = ({ onClick }) => // ✅
<button type="button" onClick={onClick}> // ✅
Click me
</button>
An obvious improvement would be to respond to the children property as well. This allows the caller of Button to write anything in place of the static Click me –
const Button = ({ onClick, children }) =>
<button type="button" onClick={onClick}>{children}</button>
<Button onClick={handleRegister}>Register</Button>
<Button onClick={handleLogin}>Login</Button>
<Button onClick={handleSave}>Save</Button>
Note children can be passed as a property. Sometimes you will see components use children in this way. Both examples function identically –
const Button = ({ onClick, children }) =>
<button
type="button"
onClick={onClick}
children={children}
/>
Another common thing for Button components like this is to automatically prevent the default event for the onClick handler. We can also accept a type property and set the default to "button" if the caller does not otherwise specify –
const Button = ({ type = "button", onClick, children, preventDefault = true }) =>
<button
type={type}
onClick={e => {
if (preventDefault) e.preventDefault()
onClick(e)
}}
children={children}
/>
<Button type="submit" onClick={handleRegister}>Register</Button>
<Button onClick={handleReset} preventDefault={false} children="Reset" />