Home > Mobile >  How to pass parameters to validate function in react-hook-form
How to pass parameters to validate function in react-hook-form

Time:07-21

I am evaluating react-hook-form for my application.

I am trying to find out a way to send dynamic values to custom validation function in react-hook-form.

We are using a library which in turn uses MUI, hence we have to use Controller component from react-hook-form.

I want to create a common validation rules file with common functions which I will be using in multiple forms. To achieve that I need to pass some values to the functions defined in validate option.

For instance for minMaxRule validation I need to define a common function which will accept min and max as parameters. I can see the types file of react-hook-form for validate will have a callback only with the value of that field. Is there any other way to achieve this ?

Form Component

import React, { BaseSyntheticEvent } from 'react';
import { Controller, useForm  } from 'react-hook-form';
import { ruleSet } from '../../utils/validation/rules';
import { Validate, FieldValues } from 'react-hook-form';

export const ReactHookFormSample = (): JSX.Element => {
    const { handleSubmit, control, formState: { errors }, getValues, register } = useForm({
        mode: "onChange"
    });

    /**
     * Call back on successful submit of form with form values
     * @param data
     * @param e
     */
    const onSubmit = (data: any, e: BaseSyntheticEvent) =>  {
        console.log('hook form', data);
    }

    /**
     * Callback when form is submitted with errors
     * @param errors
     * @param e
     */
    const one rror = (errors: any, e: BaseSyntheticEvent) =>  {
        console.log('When errors form', errors);
    }

    const getError = (field: FieldValues) => {
        let errorStr =  '';
        let inputName = field?.name;
        if (errors && errors?.[inputName]) {
            errorStr = errors?.[inputName]?.message;
        }
        return errorStr;
    }

    return (
        <>
            <h3>Sample React hook form</h3>
            <form onSubmit={handleSubmit(onSubmit, one rror)}>
                <Controller
                    name="user_name"
                    control={control}
                    rules={{ validate: {isRequired: ruleSet.isRequired, minLen: ruleSet.minLen, maxLen: ruleSet.maxLen } }}
                    render={({ field, fieldState: {error}, formState }) => 
                            <MyTextField placeholder="Enter user name here" error={!!error} {...field} />
                    }
                />
                <br/>
                <Controller
                    name="password"
                    control={control}
                    rules={{ validate: {isRequired: ruleSet.isRequired, minLen: ruleSet.minLen, maxLen: ruleSet.maxLen } }}
                    render={({ field, fieldState: {error}, formState }) => 

                            <MyTextField placeholder="Enter password here" error={!!error} {...field} />
                    }
                />
                <br/>
                <Controller
                    name="retype_password"
                    control={control}
                    rules={{ validate: {isRequired: ruleSet.isRequired, minMaxLen: ruleSet.minMaxLen, ruleSet.isValueEqual } }}
                    render={({ field, fieldState: {error}, formState }) => 
                        
                            <MyTextField placeholder="Retype password here" error={!!error} {...field} />
                    }
                />
                <br/>
                <MyButton color="primary" type="submit">
                    Submit Form
                </MyButton>
            </form>
        </>
    );
};

Common Rules file

export const isRequired = (value: string) => {
    return value ? true : 'This is a required input, can not escape';
}

export const maxLen = (value: string) => {
    // console.log('Get values', getValues());
    return value.length <= 15 || 'Value cannot be more than 15 chars';
}

const minLen = (value: string) => {
    // console.log('Get values', getValues());
    return value.length >= 7 || 'Value cannot be less than 7 chars';
}

const minMaxLen = (value: string) => { // Here i want to get dynamic parameter for min and max so that it can be used in various forms
    return value.length >= <SomeMinValue> && value.length <= <SomeMaxValue> || 'Should be between ${SomeMinValue} and ${SomeMaxValue} chars';
}

const isValueEqual = (value: string) => {
        const valOfFieldToBeComparedWith = getValues('password'); // Check how to pass params dynamically to validate function
        console.log("retype password is", valOfFieldToBeComparedWith);
        return value === valOfFieldToBeComparedWith || 'Password and retype password do not match';
    }


export const ruleSet = {
    isRequired,
    minLen,
    maxLen,
    minMaxLen,
    isValueEqual
}

I basically need a way to pass parameters to these functions defined in rules file so from the form component.

Any guidance will be highly appreciated. Thank you

CodePudding user response:

You can wrap the validation function so that you can set the min/max params.

const makeMinMaxLen = (min: number, max: number) => (value: string) => {
    return value.length >= min && value.length <= max || 'Should be between ${min} and ${max} chars';
}
<Controller
  name="retype_password"
  control={control}
  rules={{ validate: {isRequired: ruleSet.isRequired, minMaxLen: ruleSet.makeMinMaxLen(4, 16), ruleSet.isValueEqual } }}
  render={({ field, fieldState: {error}, formState }) =>
    <MyTextField placeholder="Retype password here" error={!!error} {...field} />
  }
/>

Even better is to store the composed function outside the render function

  • Related