动态创建React组件时触发Invalid hook call错误求助
解决React Invalid hook call错误
错误原因
你遇到的错误:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
是因为你直接在addLevel函数中调用Level(props)生成React元素并存储到状态中。如果Level是使用了React Hooks的函数组件,这种直接调用的方式会让Hooks脱离函数组件的执行上下文,违反了React Hooks的核心规则——Hooks必须在函数组件的顶层作用域内调用。
修复方案
不要在状态中存储已生成的React元素,而是存储组件的配置数据(即props),在渲染阶段再根据这些数据生成组件。
修改后的完整代码
export interface AppState { levels: Array<LevelProps>; // 改为存储Level组件的props数据 builtInLevels: Array<string>; }; const initialState: AppState = { levels: [], builtInLevels: ["yesterday"] }; function App() { const [state, setState] = useState<AppState>(initialState); const addLevel = (props: LevelProps) => { setState({ ...state, levels: [...state.levels, props] // 仅存储props }) }; const newLevelOnClick = (event: React.MouseEvent<HTMLButtonElement>) => { event.preventDefault(); addLevel({name: "none"}); }; return ( <div className="App"> <div> <div><button name="newLevel" value="newLevel" onClick={newLevelOnClick}>new level</button></div> </div> <div> {state.builtInLevels.map(name => <div key={name} className="m-1"><Level name={name} /></div> )} </div> <div> {state.levels.map((levelProps, index) => <div key={index} className="m-1"><Level {...levelProps} /></div> )} </div> </div> ); } export default App;
关键修改点
- 调整状态结构:将
AppState中的levels类型从Array<React.ReactElement>改为Array<LevelProps>,只存储组件的配置数据。 - 修改状态更新逻辑:
addLevel函数不再生成React元素,而是直接将传入的props添加到状态数组中。 - 渲染阶段生成组件:在渲染
levels数组时,遍历存储的props,动态生成Level组件,此时Level的Hooks会在组件的顶层作用域内执行,符合规则。
注意:示例中使用
index作为key仅为演示,实际项目中建议使用具有唯一性的标识(如生成的ID)作为key,避免因数组顺序变化导致的渲染问题。
内容的提问来源于stack exchange,提问作者Blankman
相关产品推荐
相关产品推荐

