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

React+TypeScript中useEffect报错number不可赋值给void|Destructor如何解决

报错原因
  • 第一个报错Type number is not assignable to type 'void | Destructor':你给useEffect传的回调用了不带花括号的单行箭头函数写法,此时boundsArray.push(xxx)的返回值(数组的新长度,number类型)会被作为useEffect回调的返回值。但useEffect规定回调只能返回销毁函数(Destructor)或者无返回值(void),不符合类型要求所以报错。
  • 第二个初始报错和修改后残留的类型报错:
    1. 最初的Array<number>[]是二维数字数组的类型声明,和你要存储单个数字的预期不符,修改为Array<number>后仅解决了维度不匹配的问题
    2. 你只声明了boundsArray变量没有初始化,实际值为undefined,调用push方法本身就会触发运行时错误
    3. props.elementBounds.current?.getBoundingClientRect().top用了可选链,当ref还没绑定到DOM元素时,current为null,整个表达式返回undefined,无法赋值给要求元素为number类型的数组,所以触发类型不兼容报错。
修复方案
  1. 给useEffect回调加上花括号,避免把push的返回值作为回调返回值
  2. 初始化boundsArray变量,如果需要跨渲染周期保留数组内容,建议用useRef存储(普通let变量每次组件渲染都会重置)
  3. 加判断逻辑,确保ref绑定到DOM元素后再读取top值,避免出现undefined

修复后的DraggableGameAnswers组件代码:

import { RefObject, useEffect, useRef } from 'react';

type DraggableGameAnswersProps = {
    elementBounds: RefObject<HTMLDivElement>
}

function DraggableGameAnswers(props: DraggableGameAnswersProps) {
    // 用useRef存储数组,跨渲染周期保留内容
    const boundsArrayRef = useRef<Array<number>>([]);

    useEffect(() => {
        // 先判断current是否存在,避免读取到undefined
        if (props.elementBounds.current) {
            const top = props.elementBounds.current.getBoundingClientRect().top;
            boundsArrayRef.current.push(top);
        }
        // 可根据业务需要补充依赖数组,避免useEffect重复执行
    }, [props.elementBounds])  
    
    return (
        <div className="draggable-game-answers">
            test
        </div>
    );
}

export default DraggableGameAnswers;

如果你不需要跨渲染保留数组内容,仅单次useEffect内使用,可以直接在useEffect内部声明数组,不需要在组件顶层定义。

内容的提问来源于stack exchange,提问作者Octavian Niculescu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 13:54:09