React+TypeScript中如何将TextField值传入按钮点击事件并修复Hook错误
问题修复:React Hook 调用错误的解决方案
问题描述
我是React和TypeScript新手,使用FluentUI实现了一个TextField和按钮。需要在用户输入值并点击按钮时,将TextField的输入值传入按钮的onClick事件,并用该搜索值调用API。运行代码时出现如下错误:
React Hook "useEffect" 在非React函数组件或自定义React Hook函数的onClick函数中被调用。React组件名称必须以大写字母开头,React Hook名称必须以"use"开头。
原代码如下:
export const OwnerPage: React.FunctionComponent = () => { const [TextFieldValue, setTextFieldValue] = React.useState(''); const [owner, setOwner] = useState([]); const [err, setError] = useState({}); const onClick = () => { useEffect(() => { callMsGraph(TextFieldValue) .then(response => setOwner(response)) .catch(err => setError(err)); }, []) } const onChangeTextFieldValue = React.useCallback( (event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) => { setTextFieldValue(newValue || ''); }, [], ); const stackStyles: Partial<IStackStyles> = { root: { height: 44 } }; return ( <Page> <PageHeader/> <Text variant="xxLarge">Group Details</Text> <TextField ariaLabel={"GroupId"} placeholder={"Group Id"} onChange={onChangeTextFieldValue} tabIndex={0} /> <DefaultButton onClick={onClick}>{TextFieldValue}</DefaultButton> </Page> ); };
修复方案
错误原因
useEffect是React Hook,只能在函数组件的顶层作用域或自定义Hook内部调用,不能嵌套在事件处理函数(如onClick)里。你的需求是点击按钮时触发API调用,完全不需要使用useEffect,直接在点击事件中调用API即可。
修改后的代码
import React, { useState, useCallback } from 'react'; // 导入你需要的FluentUI组件和callMsGraph方法 export const OwnerPage: React.FunctionComponent = () => { // 遵循小驼峰命名规范,优化状态变量名 const [textFieldValue, setTextFieldValue] = useState(''); // 给状态添加类型注解(根据实际API返回类型调整) const [owner, setOwner] = useState<Array<any>>([]); const [err, setError] = useState<Record<string, any>>({}); // 直接在点击事件中调用API,移除多余的useEffect const handleClick = () => { // 可选:添加输入值校验,避免空值调用API if (!textFieldValue.trim()) return; callMsGraph(textFieldValue) .then(response => setOwner(response)) .catch(error => setError(error)); }; const onChangeTextFieldValue = useCallback( (event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) => { setTextFieldValue(newValue || ''); }, [], ); const stackStyles: Partial<IStackStyles> = { root: { height: 44 } }; return ( <Page> <PageHeader/> <Text variant="xxLarge">Group Details</Text> <TextField ariaLabel="GroupId" placeholder="Group Id" onChange={onChangeTextFieldValue} tabIndex={0} // 可选:绑定value到状态,让输入框成为受控组件 value={textFieldValue} /> <DefaultButton onClick={handleClick}>搜索</DefaultButton> </Page> ); };
关键修改点
- 移除事件中的useEffect:直接在点击事件函数内调用
callMsGraph,符合React Hook的使用规则 - 优化命名规范:将
TextFieldValue改为textFieldValue,遵循React/TypeScript小驼峰命名习惯 - 添加类型注解:给
owner和err状态添加类型,提升代码的类型安全性 - 可选优化:
- 添加输入值非空校验,避免无效的API调用
- 给TextField绑定
value属性,使其成为受控组件,确保状态与输入框值同步 - 将按钮文本改为固定的"搜索",避免随输入值变化导致按钮频繁重渲染
内容的提问来源于stack exchange,提问作者user989988
相关产品推荐
相关产品推荐

