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

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>
  );
};

关键修改点

  1. 移除事件中的useEffect:直接在点击事件函数内调用callMsGraph,符合React Hook的使用规则
  2. 优化命名规范:将TextFieldValue改为textFieldValue,遵循React/TypeScript小驼峰命名习惯
  3. 添加类型注解:给owner和err状态添加类型,提升代码的类型安全性
  4. 可选优化:
    • 添加输入值非空校验,避免无效的API调用
    • 给TextField绑定value属性,使其成为受控组件,确保状态与输入框值同步
    • 将按钮文本改为固定的"搜索",避免随输入值变化导致按钮频繁重渲染

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 08:23:19