4

I have a form written using React and Formik. The form currently has 3 fields (for arguments sake, let's assume 3 strings which are validated as required fields using Yup).

If one of the fields holds a particular value I would like to remove a different field, along with the associated validation. ie if field x holds the value 'somestring', I would like field y to appear and be required, but if field x holds a value other than 'somestring', I would like field y to not appear, and consequently not be required.

I am reasonably new to React and Formik validation and so am not sure how to evaluate the current value of a field and alter the rendering based on this.

I am trying to accomplish this using Reacts function components rather than class components.

// 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

1 Answer 1

2

you should change your validation to become something like this:

conditionalTrigger: Yup.string().required(),
conditionalAffected:  Yup.string().when('conditionalTrigger', {
   is: (val) => val == "something",
   then: Yup.string().required('This field is required')
}),
Sign up to request clarification or add additional context in comments.

4 Comments

Thanking you! I had been searching through trying to make formik do the work when I should have been looking through Yup! Fair play.
You are welcome @bryansmullen i am glad i helped
@Halim @Bryansmullen This handles the validation, but doesn't the conditionalAffected field continue to show?
@kburgie yes this only handles validation, it has nothing to do with the field being displayed or not, if you want to hide the field depending on some value you can do something like: val === "something" && <p> this will be visible only if val equals something</p>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.