【问题标题】:React Formik Array Field Error Uncontrolled Inputs changing to controlledReact Formik 数组字段错误不受控制的输入更改为受控
【发布时间】:2023-02-08 14:51:43
【问题描述】:

我正在开发一个 React 前端来将表单数据发送回我的 API。我决定使用 formik 为我的应用程序创建所需的表单。在测试数组字段并尝试仅在有问题的数组元素输入字段中添加验证错误时。我遇到了这个错误。

警告:组件正在将不受控制的输入更改为受控制。这可能是由于值从 undefined 更改为 defined 值引起的,这不应该发生。在组件的生命周期内决定使用受控或非受控输入元素。更多信息:

我已经成功地为除数组字段之外的其他字段实现了我的表单和错误,所以我尝试添加带有正确数组元素索引作为名称的 ErrorMessage 标记,这是错误首先显示其毒牙的时候。

这是我的组件代码:

我试图深入研究错误并找到自己的解决方案,但我看到的所有其他讨论此错误的堆栈溢出答案都太复杂了,我无法理解。如果有人可以提供帮助,如果您对我如何清理这段代码有任何提示,我将不胜感激,我会认为它不是最漂亮的。

import { useDispatch } from "react-redux";
import {Formik, Form, Field, FieldArray, ErrorMessage} from 'formik'
import * as Yup from 'yup'
const Sign = () => {
    const ciscoDomainRegex = new RegExp('.*\.cisco\.com')
    const SignSchema = Yup.object({
        hostname:Yup.string().matches(ciscoDomainRegex, 'Hostname Must Be A Cisco Domain').required('required'),
        sans:Yup.array().of(Yup.string().matches(ciscoDomainRegex)),
        csr:Yup.mixed()
    })

    const dispatch = useDispatch()

    const showError = (errors, field)=>{
        switch (field){
            case 'hostname':
                return <p>{errors.hostname}</p>
            case 'sans':
                return <p>{errors.sans}</p>
            case 'csr':
                return <p>{errors.csr}</p>
            default:
                return false
        }
    }

    return ( 
    <div>
        Sign Page
        <Formik
        initialValues={{
            hostname:'',
            sans:[''],
            csr:null
        }}
        validationSchema={SignSchema}
        onSubmit={(values)=>console.log(values)}
        >
            {({errors, touched, setFieldValue})=>{
                return(
            <Form className="form-center">
                <Field className="form-control mt-1" name='hostname' placeholder="Enter Hostname"/>
                {/* {errors && touched.hostname ? showError(errors, 'hostname') : null} */}
                <ErrorMessage name="hostname"/>
                <FieldArray  name="sans" placeholder='Enter Sans'>
                    {({push, remove, form})=>{
                        const {sans} = form.values
                        return (
                            <div>
                                {
                                    sans.map((san, i)=>{
                                        return (
                                            <div className="input-group" key={i}>
                                                <Field className="form-control mt-1" name={`sans${i}`} placeholder="Enter San"/>
                                                {/* {errors && touched.sans ? showError(errors, 'sans') : null} */}
                                                <ErrorMessage name={`sans${i}`}/>
                                                <div className="input-group-append">
                                                    <button className="btn btn-secondary float-end" type="button" onClick={()=>remove(i)}>-</button>
                                                    <button className="btn btn-secondary" type="button" onClick={()=>push('')}>+</button>
                                                </div>
                                            </div>
                                        )
                                    })
                                }
                            </div>
                            )        
                    }}
                </FieldArray>
                <input className="form-control mt-1" type="file" name='csr' onChange={(e)=>setFieldValue('csr',e.currentTarget.files[0])}/>
                {errors && console.log(errors)}
                <button className="btn btn-primary" type="submit">Submit</button>
            </Form>
             )
            }}
        </Formik>
    </div>
     );
}
 
export default Sign;

【问题讨论】:

  • 该字段的名称应该是 sans[${i}] 或 sans.${i} 而不是 sans${i}
  • 谢谢你,我其实只是想明白了,不过

标签: javascript reactjs arrays formik


【解决方案1】:

您为将动态添加的每个字段传递了错误的字段名称。

每个字段名称应该是 name[index] 像这样...

<字段名={san[$(index)]/>

或者你也可以使用点符号来引用字段数组中的特定字段

PS:不要忘记使用反引号

【讨论】:

    猜你喜欢
    • 2021-05-21
    • 1970-01-01
    • 2017-06-30
    • 2021-07-29
    • 2021-01-30
    • 2020-11-04
    • 2022-11-28
    • 2020-11-01
    • 2017-07-25
    相关资源
    最近更新 更多