【问题标题】:Conditionally render Formik field with validation based on input values of another field in React根据 React 中另一个字段的输入值,有条件地渲染 Formik 字段并进行验证
【发布时间】:2021-03-15 14:44:58
【问题描述】:

我有一个使用 React 和 Formik 编写的表单。该表单目前有 3 个字段(为了参数,我们假设 3 个字符串使用 Yup 验证为必填字段)。

如果其中一个字段包含特定值,我想删除一个不同的字段以及相关的验证。即,如果字段 x 包含值“somestring”,我希望字段 y 出现并被要求,但如果字段 x 包含除“somestring”以外的值,我希望字段 y 不出现,因此不需要。

我对 React 和 Formik 验证相当陌生,因此不确定如何评估字段的当前值并基于此更改呈现。

我正在尝试使用 Reacts 函数组件而不是类组件来完成此任务。

// react imports
import React, {useContext} from "react";
// style imports
import './NewUser.css'

// hook & context imports
import {useHttpClient} from "../../../Shared/hooks/http-hook";
import AuthContext from "../../../Shared/context/auth-context";

// form validation imports
import * as Yup from 'yup';
import {Field, Form, Formik} from 'formik';


const NewUser = () => {
    const auth = useContext(AuthContext)
    const {sendRequest} = useHttpClient()

    const SignupSchema = Yup.object().shape({
        name: Yup.string().required(),
        conditionalTrigger: Yup.string().required(), // if this field holds 'somestring' then conditionalAffected should render
        conditionalAffected: Yup.string().required()
    });

    return (
                    <Formik
                        initialValues={{
                            name: '',
                            conditionalTrigger: '',
                            conditionalAffected: ''
                        }}
                        validationSchema={SignupSchema}

                        onSubmit={async values => {
                            const response = await sendRequest(
                                `${process.env.REACT_APP_BACKEND_URL}/users/create`,
                                'POST',
                                JSON.stringify(values),
                                {
                                    'Content-Type': 'application/json',
                                    Authorization: 'Bearer ' + auth.token
                                }
                            )
                        }}
                    >
                        {({errors, touched}) => (

                            <Form>
                                <Field name="name" placeholder={"Name"}/>
                                {errors.name && touched.name ? (
                                    <div>{errors.name}</div>
                                ) : null}
                            <Field name="conditionalTrigger" placeholder={"conditionalTrigger"}/>
                                {errors.conditionalTrigger && touched.conditionalTrigger ? (
                                    <div>{errors.conditionalTrigger}</div>
                                ) : null}
                            <Field name="conditionalAffected" placeholder={"conditionalAffected"}/>
                                {errors.conditionalAffected && touched.conditionalAffected ? (
                                    <div>{errors.conditionalAffected}</div>
                                ) : null}


                                <button className={'btn red'} type="submit">Submit</button>
                            </Form>
                        )}
                    </Formik>
    )
}

export default NewUser

【问题讨论】:

    标签: reactjs formik yup


    【解决方案1】:

    您应该将验证更改为如下所示:

    conditionalTrigger: Yup.string().required(),
    conditionalAffected:  Yup.string().when('conditionalTrigger', {
       is: (val) => val == "something",
       then: Yup.string().required('This field is required')
    }),
    

    【讨论】:

    • 谢谢!我一直在寻找让 formik 完成工作的过程,而我应该一直在寻找是的!公平竞争。
    • 不客气@bryansmullen 我很高兴我帮助了
    • @Halim @Bryansmullen 这会处理验证,但conditionalAffected 字段不会继续显示吗?
    • @kburgie 是的,这仅处理验证,它与是否显示字段无关,如果您想根据某个值隐藏该字段,您可以执行以下操作:val === "something" &amp;&amp; &lt;p&gt; this will be visible only if val equals something&lt;/p&gt;
    猜你喜欢
    • 2021-01-19
    • 2019-03-25
    • 1970-01-01
    • 2020-08-04
    • 2020-11-19
    • 2011-09-20
    • 2018-09-04
    • 2017-02-28
    • 1970-01-01
    相关资源
    最近更新 更多