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

React + React Hook Form中动态创建元素的颜色修改方案咨询

React Hook Form useFieldArray 动态元素样式修改方案

核心思路

动态生成的元素可通过自身index或字段值做条件判断,动态绑定className或style属性,实现样式切换。

具体实现方法

1. 基于选中项index定位样式

如果需要根据用户选择(比如点击选中某一行)修改样式,用状态存储选中的index,渲染时做判断:

import { useForm, useFieldArray } from "react-hook-form";
import { useState } from "react";

function DynamicForm() {
  const { register, control } = useForm({
    defaultValues: {
      items: [{ name: "", type: "" }]
    }
  });
  const { fields, append, remove } = useFieldArray({
    control,
    name: "items"
  });
  // 存储选中的元素index
  const [selectedIndex, setSelectedIndex] = useState(null);

  return (
    <form>
      {fields.map((item, index) => (
        <div
          key={item.id}
          // 根据是否选中动态添加类名
          className={`dynamic-item ${index === selectedIndex ? "selected" : ""}`}
          onClick={() => setSelectedIndex(index)}
        >
          <input
            {...register(`items[${index}].name`)}
            placeholder="输入名称"
          />
          <select {...register(`items[${index}].type`)}>
            <option value="normal">普通</option>
            <option value="highlight">高亮</option>
          </select>
          <button type="button" onClick={() => remove(index)}>删除</button>
        </div>
      ))}
      <button type="button" onClick={() => append({ name: "", type: "" })}>添加项</button>
    </form>
  );
}

对应的CSS:

.dynamic-item {
  padding: 10px;
  margin: 8px 0;
  border: 1px solid #ddd;
}
.dynamic-item.selected {
  border-color: #2196f3;
  background-color: #e3f2fd;
}

2. 基于字段自身值的样式切换

如果根据动态项内部的表单值(如下拉框选择)修改样式,直接读取字段value即可,无需额外状态:

{fields.map((item, index) => (
  <div
    key={item.id}
    style={{
      padding: "10px",
      margin: "8px 0",
      border: "1px solid #ddd",
      // 根据当前项的type值切换背景色
      backgroundColor: item.type === "highlight" ? "#fff3e0" : "#fff"
    }}
  >
    <input {...register(`items[${index}].name`)} placeholder="输入名称" />
    <select {...register(`items[${index}].type`)}>
      <option value="normal">普通</option>
      <option value="highlight">高亮</option>
    </select>
    <button type="button" onClick={() => remove(index)}>删除</button>
  </div>
))}

3. 批量选中场景的扩展

如果需要支持多选,把状态改成数组存储选中index,判断时用includes:

const [selectedIndexes, setSelectedIndexes] = useState([]);

// 切换选中状态的函数
const toggleSelect = (index) => {
  setSelectedIndexes(prev => 
    prev.includes(index) 
      ? prev.filter(i => i !== index) 
      : [...prev, index]
  );
};

// 渲染时的类名判断
className={`dynamic-item ${selectedIndexes.includes(index) ? "selected" : ""}`}

关键注意点

  • 必须用item.id作为元素key,而非index——useFieldArray删除元素时index会变化,item.id是库生成的唯一标识,避免React渲染错误。
  • 简单样式用内联style快捷,复杂样式优先用CSS类,更易维护扩展。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 03:45:03