React TypeScript中带可选参数的onClick直接绑定问题及useToggle自定义Hook适配咨询
toggleValue to React onClick Hey there! Let's break down why you're hitting this TypeScript error and how to fix it so you can bind toggleValue directly to your button's onClick without wrapping it in an extra callback.
The Root of the Problem
React's onClick event expects a callback function with this signature:
(event: React.MouseEvent<HTMLButtonElement>) => void
But your current toggleValue has a signature of (value?: boolean) => void. When you try to bind toggleValue directly, TypeScript sees that onClick will pass a MouseEvent to the function—but toggleValue only accepts boolean | undefined. That's the type mismatch causing the error.
Solution 1: Make toggleValue Accept Both boolean and MouseEvent
We can adjust the function to handle both cases: when it's called with a boolean (to set a specific value) or with a MouseEvent (from the button click, to toggle the value).
Here's the updated code:
import { useState, MouseEvent } from 'react'; export default function useToggle(defaultValue: boolean = false) { const [value, setValue] = useState(defaultValue); const toggleValue = (valueOrEvent?: boolean | MouseEvent) => { setValue((currentValue) => { // Check if we got a mouse event (from onClick) if (valueOrEvent instanceof MouseEvent) { return !currentValue; } // Otherwise use the boolean value if provided, or toggle return typeof valueOrEvent === 'boolean' ? valueOrEvent : !currentValue; }); }; return [value, toggleValue] as const; }
Now you can bind it directly:
<button onClick={toggleValue}>toggle</button>
And still use the explicit value calls:
<button onClick={() => toggleValue(true)}>set True</button> <button onClick={() => toggleValue(false)}>set False</button>
Solution 2: Use Function Overloads (More Explicit Type Safety)
If you want to make the function's intended uses clearer to TypeScript, you can define function overloads. This tells TypeScript exactly what call signatures are allowed.
import { useState, MouseEvent } from 'react'; export default function useToggle(defaultValue: boolean = false) { const [value, setValue] = useState(defaultValue); // Define allowed call signatures function toggleValue(): void; function toggleValue(targetValue: boolean): void; function toggleValue(event: MouseEvent): void; // The actual implementation function toggleValue(input?: boolean | MouseEvent) { setValue((currentValue) => { if (input instanceof MouseEvent) { return !currentValue; } return typeof input === 'boolean' ? input : !currentValue; }); } return [value, toggleValue] as const; }
This approach gives you stricter type checking—TypeScript will only allow the three defined ways to call toggleValue, which makes your code more maintainable.
Why This Works
Both solutions make toggleValue compatible with the onClick callback signature by letting it accept the MouseEvent parameter that React will pass. When the function is triggered by a button click, it just toggles the current value instead of trying to use the event object as a boolean.
内容的提问来源于stack exchange,提问作者Rex

