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

React函数组件动态创建React.Dispatch及管控输入如何避免Hook报错

解决方案

错误原因

你遇到的报错是因为违反了React Hook的调用规则:useState 仅允许在函数组件的最顶层作用域调用,不能嵌套在回调函数、循环、条件分支中,你之前将useState写在addVal点击回调内,自然会触发规则报错。

实现方案

由于你无法单独封装列表项组件,我们可以将所有输入项的状态统一存在组件顶层的useState中,通过唯一标识匹配对应输入项做更新,完全适配Fluent UI的onRenderItemColumn使用场景:

import { useState, useCallback } from 'react';

interface InputItem {
  id: number; // 用唯一标识匹配对应输入项
  value: string;
}

function MyReactFunction() {
  const [allVals, setAllVals] = useState<InputItem[]>([]);

  // 新增输入项
  const addVal = useCallback(() => {
    setAllVals(prev => [
      ...prev,
      { 
        id: Date.now(), // 用时间戳作为简易唯一id,也可以用自增数字
        value: '' 
      }
    ]);
  }, []);

  // 更新指定输入项的值
  const handleInputChange = useCallback((id: number, newValue: string) => {
    setAllVals(prev => 
      prev.map(item => 
        item.id === id ? {...item, value: newValue} : item
      )
    );
  }, []);

  // 提交时获取所有值
  const handleSubmit = useCallback(() => {
    const valueList = allVals.map(item => item.value);
    // 后续处理提交逻辑
    console.log(valueList);
  }, [allVals]);

  // 原生渲染示例,可直接替换为Fluent UI组件逻辑
  return (
    <div>
      <button type="button" onClick={addVal}>Add input</button>
      <ul>
        {allVals.map(item => (
          <li key={item.id}>
            <input 
              value={item.value} 
              onChange={e => handleInputChange(item.id, e.target.value)} 
            />
          </li>
        ))}
      </ul>
      <button type="button" onClick={handleSubmit}>提交</button>
    </div>
  );
}

Fluent UI适配说明

如果你使用Fluent UI的DetailsList/List组件,只需将allVals作为items属性传递给组件,在onRenderItemColumn回调中直接拿到当前渲染的item对象,绑定value和onChange即可,无需自定义列表项组件:

import { DetailsList } from '@fluentui/react';

// 组件内return部分示例
return (
  <div>
    <button type="button" onClick={addVal}>Add input</button>
    <DetailsList
      items={allVals}
      onRenderItemColumn={(item, _index, column) => {
        if (column?.key === 'inputColumn') {
          return (
            <input 
              value={item.value}
              onChange={e => handleInputChange(item.id, e.target.value)}
            />
          )
        }
        return null;
      }}
      columns={[
        { key: 'inputColumn', name: '输入项', minWidth: 300 }
      ]}
    />
    <button type="button" onClick={handleSubmit}>提交</button>
  </div>
)

方案合规性说明

  • 所有Hook均在组件顶层调用,不会触发Hook规则报错
  • 满足你提出的所有需求:点击新增输入、输入内容正常回显、提交时可直接获取所有输入值组成的数组
  • 配合useCallback缓存函数引用,结合React的列表key优化,不会产生多余的DOM重渲染
  • 无需封装单独的列表项组件,完全适配Fluent UI的onRenderItemColumn使用逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:57:02