You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React TypeScript中带可选参数的onClick直接绑定问题及useToggle自定义Hook适配咨询

Fixing Type Mismatch for Directly Binding 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 08:57:39