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

React Formik FieldArray的push与remove方法失效问题排查

问题描述

我想实现一个动态表单,参考教程用Formik的remove和push方法。现在浏览器能渲染所有数据,但点击“Delete”或“Add”按钮完全没反应,也没报错,不知道怎么调试修复。

另外,教程里作者用了values作为默认Props获取数据,我没这么做,会不会是问题根源?values的使用场景是什么?作者没解释。

附上代码:

function CreateTestSuite3() {

    const initialValues = {
        testSuite: { 
            tsId: 0,
            tsName: "",
            tsDescription: "",
            testCases: [ 
                {
                testCaseNumber: 0,
                testCaseName: "",
                testCaseEnvironment: "",
                testCaseSQL: ""
                }
            ]
        }
    }; 

    const onSubmit = (data) => { 
        console.log("this is form data: ", data); 
        axios.post("http://localhost:8080/TestSuite/CreateTestSuite", data)
            .then((response) => {
                console.log("Form Submitted");
        })
    };

    return (
        <div className="CreateTestSuite">
            <Formik initialValues={initialValues} onSubmit={onSubmit}>
                <Form className="formContainer">
                    <label>Test Suite Id: </label>
                    <ErrorMessage name="tsId" component="span" />
                    <Field autoComplete="off" name="testSuite.tsId" placeholder="tsId" />

                    <label>Test Suite Name: </label>
                    <ErrorMessage name="tsName" component="span" />
                    <Field autoComplete="off" name="testSuite.tsName" placeholder="tsName" />

                    <label>Test Suite Description: </label>
                    <ErrorMessage name="tsDescription" component="span" />
                    <Field autoComplete="off" name="testSuite.tsDescription" placeholder="tsDescription" />

                    <FieldArray name="testSuite.testCases">
                        {({push, remove, }) => (
                            <>
                            {initialValues.testSuite.testCases.map((TestCase, index) => (
                                    <div key={index}>

                                        <label>Test Case Number: </label>
                                        <Field name={`TestCase.${index}.testCaseNumber`} placeholder="testCaseNumber" ></Field>

                                        <label>Test Case Name: </label>
                                        <Field name={`TestCase.${index}.testCaseName`} placeholder="testCaseName" ></Field>

                                        <label>Test Case Environment: </label>
                                        <Field name={`TestCase[${index}].testCaseEnvironment`} placeholder="testCaseEnvironment" ></Field>

                                        <label>Test Case SQL: </label>
                                        <Field name={`TestCase[${index}].testCaseSQL`} placeholder="testCaseSQL" ></Field>

                                        <button type="button" onClick={() => remove(index)} >Delete</button>
                                    </div>
                             ))}
                                
                                <button type="button" onClick={() => push({ testCaseNumber: 0, testCaseName: "", testCaseEnvironment: "", testCaseSQL: "" })}>Add Test Case</button>
                            </>
                        )}
                    </FieldArray>

                    <button type="submit">Create Test Suite</button>

                </Form>
            </Formik>
        </div>
    )
}
问题修复

你的代码有两个核心问题导致按钮无响应:

1. 遍历静态初始值而非Formik实时状态

你用initialValues.testSuite.testCases.map渲染列表,但initialValues是组件初始化时的静态数据,不会随Formik内部状态更新而变化。点击push/remove后Formik状态已经改变,但你仍在渲染旧的初始列表,所以看不到界面变化,且remove操作的索引也无法对应实时数据。

修复:从FieldArray的render props中获取form对象,用form.values.testSuite.testCases遍历:

<FieldArray name="testSuite.testCases">
  {({ push, remove, form }) => (
    <>
      {form.values.testSuite.testCases.map((testCase, index) => (
        // 渲染列表项
      ))}
      {/* Add按钮 */}
    </>
  )}
</FieldArray>

2. Field的name属性路径错误

你写的TestCase.${index}.xxx或TestCase[${index}].xxx路径不正确,Formik中数组的实际路径是testSuite.testCases,正确的name应该是testSuite.testCases[${index}].testCaseNumber(或点语法testSuite.testCases.${index}.testCaseNumber)。路径错误会导致控件无法绑定到Formik状态,也会影响push/remove的有效性。

修复后的Field示例:

<Field name={`testSuite.testCases[${index}].testCaseNumber`} placeholder="testCaseNumber" />

完整修复后的FieldArray代码

<FieldArray name="testSuite.testCases">
  {({ push, remove, form }) => (
    <>
      {form.values.testSuite.testCases.map((testCase, index) => (
        <div key={index}>
          <label>Test Case Number: </label>
          <Field name={`testSuite.testCases[${index}].testCaseNumber`} placeholder="testCaseNumber" />

          <label>Test Case Name: </label>
          <Field name={`testSuite.testCases[${index}].testCaseName`} placeholder="testCaseName" />

          <label>Test Case Environment: </label>
          <Field name={`testSuite.testCases[${index}].testCaseEnvironment`} placeholder="testCaseEnvironment" />

          <label>Test Case SQL: </label>
          <Field name={`testSuite.testCases[${index}].testCaseSQL`} placeholder="testCaseSQL" />

          <button type="button" onClick={() => remove(index)}>Delete</button>
        </div>
      ))}
      <button type="button" onClick={() => push({ testCaseNumber: 0, testCaseName: "", testCaseEnvironment: "", testCaseSQL: "" })}>Add Test Case</button>
    </>
  )}
</FieldArray>
关于values的疑问

教程里的values是Formik当前的实时表单状态值,是Formik通过render props传递的核心数据:

  • 使用场景:当你需要获取表单当前状态(比如遍历动态数组、根据表单值做条件渲染)时,必须用values而非initialValues——因为initialValues仅在组件初始化时赋值一次,后续表单状态更新不会改变它。
  • 你之前不用values直接用initialValues,正是按钮点击后界面不更新的核心原因:你始终在渲染静态初始列表,没有同步Formik的实时状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 15:05:24