点击按钮传ID调用API获取数据时遇无效Hook调用错误求助
修复React无效Hook调用的问题
问题根源
你直接通过onClick={() => EditExercise(item.idexercise)}调用EditExercise函数,但这个函数内部使用了useState、useEffect等Hook。React的Hook规则明确要求:Hook只能在React函数组件的顶层,或者自定义Hook的顶层调用,在事件回调里直接调用包含Hook的函数会违反这个规则,导致无效Hook调用的错误。
修复方案
1. 父组件改用状态控制编辑组件的渲染
在你的index.js里,添加一个状态来记录选中的编辑ID,点击按钮时更新这个状态,然后通过条件渲染的方式加载EditExercise组件,而不是直接调用函数。
修改后的父组件示例:
import { useState } from 'react'; import EditExercise from './EditExercise'; function ExerciseList() { const [exercises, setExercises] = useState([]); // 新增状态:记录选中要编辑的ID const [selectedEditId, setSelectedEditId] = useState(null); // 原有的获取列表数据逻辑... return ( <div> {/* 渲染数据行 */} {exercises.map(item => ( <div key={item.idexercise}> <span>{item.exerciseName}</span> {/* 点击时设置选中ID,而非直接调用EditExercise */} <button onClick={() => setSelectedEditId(item.idexercise)}>编辑</button> </div> ))} {/* 当有选中ID时,渲染编辑组件 */} {selectedEditId && <EditExercise id={selectedEditId} />} </div> ); }
2. 修正EditExercise组件的细节问题
同时,你的EditExercise组件还有几个小问题需要调整:
- 模板字符串要用反引号,否则变量
id不会被解析 - input标签需要用
value属性绑定数据,不能直接把内容作为子节点 - useEffect的依赖数组要加入
id,确保ID变化时重新发起请求 - 初始化
item用空对象更合理(因为返回的是单个数据对象)
修改后的EditExercise.jsx示例:
import { useState, useEffect } from 'react'; // 改为通过props接收id function EditExercise({ id }) { const [error, setError] = useState(null); const [isLoaded, setIsLoaded] = useState(false); const [item, setItem] = useState({}); useEffect(() => { // 用反引号包裹模板字符串 fetch(`http://localhost:5000/Exercises/GetEditId?id=${id}`) .then(res => { // 额外添加请求成功校验 if (!res.ok) throw new Error('请求出错'); return res.json(); }) .then( (result) => { setIsLoaded(true); setItem(result); }, (error) => { setIsLoaded(true); setError(error); } ) }, [id]) // 加入id到依赖数组,触发重新请求 if (error) { return <div>Error: {error.message}</div>; } else if (!isLoaded) { return <div>Loading...</div>; } else { return ( <div> {/* 用value绑定数据,闭合input标签 */} <input type="text" id="name" value={item.exerciseName || ''} /> <input type="text" id="desc" value={item.instructions || ''} /> </div> ); } } export default EditExercise;
为什么这么改
React需要追踪Hook的调用顺序,确保每次渲染时Hook的调用顺序一致。直接在事件回调里调用包含Hook的函数,会让Hook的调用脱离React的组件渲染流程,导致React无法正确追踪,从而抛出无效Hook调用的错误。通过条件渲染组件的方式,EditExercise会作为正常的React组件被渲染,Hook也会在组件的顶层被调用,符合规则。
内容的提问来源于stack exchange,提问作者MeLlmaoEphteban
相关产品推荐
相关产品推荐

