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,直接违反了这个规则。
修正方案
- 在你的函数组件顶层调用
useSessionStorage,获取用于修改SessionStorage的方法(假设useSessionStorage返回类似[storedValue, setStoredValue]的数组,和useState用法一致) - 在按钮的点击事件中,直接调用这个修改方法来保存数据,而不是调用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
相关产品推荐
相关产品推荐

