如何使用react-final-form多屏幕正确验证表单值? [英] How to properly validate form values with react-final-form multiple screen?

查看:146
本文介绍了如何使用react-final-form多屏幕正确验证表单值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将react-final-form与材料ui,mui-rff和yup一起用于表单验证.我有多个屏幕,或者我应该说向导屏幕,每个屏幕都有HTML表单元素输入和单选按钮.

所有HTML表单元素都是必需的,这意味着除非用户输入数据或单击它,否则它们无法进入下一个屏幕.

目前我在这里有2个问题.

  1. 下一个按钮无法正常工作.我希望当前屏幕的值为 valid:false 时总有错误,下一个按钮被禁用,因此无法继续下一个屏幕.屏幕值 valid:true 可以进入下一个屏幕.
  2. 表单验证正在对下一个屏幕进行高级验证,而无需单击下一步按钮.因此有效性值始终为 valid:false .这就是我所注意到的.

这是我的部分代码,有关完整的演示,请参见codeandbox.

 从"react-final-form"导入{表单};从"mui-rff"导入{makeValidate};从"yup"导入*作为yup;const initialValues = {选项:"optionB",用户:{fname:",姓氏:",座右铭:",国家/地区:"},状态:"};constvalidationSchema = yup.object({选项:yup.string().required("option required"),用户:yup.object({fname:yup.string().required("fname required"),姓氏:yup.string().required(所需的姓氏"),座右铭:yup.string().required(需要座右铭"),国家/地区:yup.string().required(需要国家/地区")}),状态:yup.string().required(需要状态")});//makeValidate是一个mui-rff函数const validate = makeValidate(validationSchema);<表格initialValues = {initialValues}validate = {validate}keepDirtyOnReinitializeinitialValuesEqual = {()=>真的}onSubmit = {()=>console.log(已提交")}render = {({handleSubmit,values,valid,errors})=>(< form onSubmit = {handleSubmit}><按钮禁用= {activeStep === 0}onClick = {handleBack}className = {classes.backButton}>后退</按钮><按钮变体=包含的".color =原色"禁用= {!有效}//如果当前没有错误,则通常为"valid";变为true,否则为false,因此如果有效为false则将其禁用,简而言之,您将无法继续.这部分是根本无法工作的越野车.onClick = {handleNext}>{activeStep === steps.length-1?完成":" Next"}</按钮></form>)}/>---------------------------屏幕----------------------------------------------//屏幕1从"mui-rff"导入{Radios};const Screen1 =()=>{返回 (< div>这是Screen1< br/>< br/><收音机label =选择选项"名称=选项"formControlProps = {{边距:无";}}radioGroupProps = {{行:true}}数据= {[{标签:"optionA",值:"optionA";},{标签:"optionB",值:"optionB";},{标签:"optionC",值:"optionC";}]}/></div>);};//屏幕2从"mui-rff"导入{TextField};const Screen2 =()=>{返回 (< div>这是Screen2< br/>< br/>< TextField name =" user.fname" ;;变体=概述的".required = {true}/>< TextField name =" user.lastname"变体=概述的".required = {true}/>< TextField name =" user.motto"变体=概述的".required = {true}/>< TextField name =" user.country"变体=概述的".required = {true}/></div>);};//屏幕3从"mui-rff"导入{TextField};const Screen3 = () =>{返回 (< div>这是Screen3< br/>< br/>< TextField name =状态";变体=概述的".required = {true}/></div>);}; 

解决方案

向导格式很难验证.我根本没有解决问题.我的解决方法是代替我在< Field/> 级别验证中确定的< form/> 级别验证.

在mui-rff中,在我通过< TextField fieldProps = {{validate:isRequired}}/> 的情况下,您可以传递react-final-form道具,其中 isRequired 我的自定义验证

I'm using react-final-form together with material ui, mui-rff and yup for form validations. I have multiple screens or should I say WIZARD SCREENS each screen has HTML form elements input and radio button.

all HTML form elements are required meaning they can't proceed to next screen unless user input data or click on it.

At the moment I have 2 problems here.

  1. The next button is not working as expected. I expect when current screen has value valid: false in short has errors next button is disabled so can't proceed to next screen. when screen value valid: true can proceed to next screen.
  2. The form validation is doing advanced validation for the next screen without clicking next button. so validity value is always valid:false. That's what I have noticed.

Here's my partial code, see codesandbox for full demo of this.

    import { Form } from "react-final-form";
    import { makeValidate } from "mui-rff";
    import * as yup from "yup";

 

     const initialValues = {
        option: "optionB",
        user: {
          fname: "",
          lastname: "",
          motto: "",
          country: ""
        },
        status: ""
      };
    
      const validationSchema = yup.object({
        option: yup.string().required("option required"),
        user: yup.object({
          fname: yup.string().required("fname required"),
          lastname: yup.string().required("lastname required"),
          motto: yup.string().required("motto required"),
          country: yup.string().required("country required")
        }),
        status: yup.string().required("status required")
      });
    
      // makeValidate is a mui-rff function
      const validate = makeValidate(validationSchema);



       <Form
       initialValues={initialValues}
       validate={validate}
       keepDirtyOnReinitialize
       initialValuesEqual={() => true}
       onSubmit={() => console.log("submitted")}
       render={({ handleSubmit, values, valid, errors }) => (
       <form onSubmit={handleSubmit}>                    
       <Button
            disabled={activeStep === 0}
            onClick={handleBack}
            className={classes.backButton}
       >
                          Back
                        </Button>
                        <Button
                          variant="contained"
                          color="primary"
                          disabled={!valid} 
// normally if the current has no error "valid" becomes true , false otherwise so to disabled if valid is false, in short you can't proceed. 
                          this part is buggy not working at all.
                          onClick={handleNext}
                        >
                          {activeStep === steps.length - 1 ? "Finish" : "Next"}
                        </Button>
                   </form>
                  )}
                />


    --------------------------- screens ----------------------------------------------
  

  // screen 1
 import { Radios } from "mui-rff";
 const Screen1 = () => {
 return (
       <div>
               This is Screen1
           <br />
           <br />
           <Radios
           label="select option"
           name="option"
           formControlProps={{ margin: "none" }}
           radioGroupProps={{ row: true }}
           data={[
           { label: "optionA", value: "optionA" },
           { label: "optionB", value: "optionB" },
           { label: "optionC", value: "optionC" }
           ]}
            />
        </div>
         );
    };
    
    // screen 2
    import { TextField } from "mui-rff";
    const Screen2 = () => {
      return (
        <div>
          This is Screen2
          <br />
          <br />
          <TextField name="user.fname" variant="outlined" required={true} />
          <TextField name="user.lastname" variant="outlined" required={true} />
          <TextField name="user.motto" variant="outlined" required={true} />
          <TextField name="user.country" variant="outlined" required={true} />
        </div>
      );
    };
    
    // screen 3
    import { TextField } from "mui-rff";
    const Screen3 = () => {
      return (
        <div>
          This is Screen3
          <br />
          <br />
          <TextField name="status" variant="outlined" required={true} />
        </div>
      );
    };

codesandbox

links:

I can confirmed yup validation is working well like you seen on this screenshot below.

解决方案

Wizard form is quite troublesome to validate. I haven't solved the problem at all. My workaround is instead of <form /> level validation I have settled in <Field /> level validation.

In mui-rff you can pass react-final-form props in my case I pass <TextField fieldProps={{ validate: isRequired }} /> where isRequired my custom validation

这篇关于如何使用react-final-form多屏幕正确验证表单值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆