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

React按钮点击调用Hook报错:无效Hook调用问题求解

解决React Hook调用错误:无法在点击事件中调用Hook

点击表格行的按钮时,尝试将行数据保存到SessionStore,却抛出错误:Invalid hook call. Hooks can only be called inside of the body of a function component.

原错误代码示例

import { useSessionStorage } from "../components/SessionStore";

// 尝试在点击事件中调用这个自定义Hook,但触发错误
function useStore(tableName, row) {
    useSessionStorage(tableName, row);
}

// 表格列配置(react-bootstrap-table-next)
const endPoint = [
    {
        dataField: 'df1',
        isDummyField: true,
        text: '本地存储',
        formatter: (cellContent, row) => {
            return (
                <button type="button" className="btn btn-light"
                    onClick={() => {
                        useStore("editTable", row); // 这里调用Hook导致错误
                    }}
                >{row.id}</button>
            );
        },
        editable: false
    }
];

问题根源

React Hook的规则明确要求:Hook只能在函数组件的顶层作用域,或者自定义Hook的顶层作用域中调用,不能在事件处理函数、循环、条件判断或嵌套函数内调用。你现在在按钮的onClick事件回调里调用自定义Hook,直接违反了这个规则。

修正方案

  1. 在你的函数组件顶层调用useSessionStorage,获取用于修改SessionStorage的方法(假设useSessionStorage返回类似[storedValue, setStoredValue]的数组,和useState用法一致)
  2. 在按钮的点击事件中,直接调用这个修改方法来保存数据,而不是调用Hook。

修改后的代码示例

import { useSessionStorage } from "../components/SessionStore";
import BootstrapTable from "react-bootstrap-table-next";

// 这段代码必须放在你的函数组件内部,不能在组件外面
function YourTableComponent() {
    // 在组件顶层调用Hook,获取存储方法
    const [, setSessionData] = useSessionStorage("editTable");

    // 表格列配置
    const endPoint = [
        {
            dataField: 'df1',
            isDummyField: true,
            text: '本地存储',
            formatter: (cellContent, row) => {
                return (
                    <button type="button" className="btn btn-light"
                        onClick={() => {
                            // 直接调用存储方法保存行数据
                            setSessionData(row);
                        }}
                    >{row.id}</button>
                );
            },
            editable: false
        }
    ];

    // 渲染表格
    return <BootstrapTable columns={endPoint} data={yourTableData} />;
}

补充说明

如果你的useSessionStorage自定义Hook需要动态指定tableName,可以调整Hook的实现,让存储方法接受键名和值两个参数:

// SessionStore.js 中的自定义Hook示例
export function useSessionStorage() {
    const setItem = (key, value) => {
        sessionStorage.setItem(key, JSON.stringify(value));
    };
    // 可选:添加获取值的逻辑
    const getItem = (key) => {
        const data = sessionStorage.getItem(key);
        return data ? JSON.parse(data) : null;
    };
    return [getItem, setItem];
}

此时点击事件中可以这样调用:

onClick={() => setSessionData("editTable", row)}

内容的提问来源于stack exchange,提问作者TBD QDBA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 21:18:32