useEffect根据填写的输入触发地址验证

时间:2019-09-12 14:45:40

标签: reactjs

我需要运行地址验证api调用。在这些情况下

   *when all associated fields are filled out.
   *when above call is done , it should be calling when any of the fields value has 
   changed.

我尝试触发将所有字段作为useEffects第二个参数数组中的依赖项,但是它反复调用效果

const Address = props => {
const { countries, usStates, caStates, title, binding, formik } = props;

var zip = formik.values.Client.Address.Residential.Zip;
var city = formik.values.Client.Address.Residential.City;
var line1 = formik.values.Client.Address.Residential.Address1;
var country = formik.values.Client.Address.Residential.Country;
var state = formik.values.Client.Address.Residential.State;


useEffect(() => {
    if (zip && city && country && state && country) {
        console.log("call address verification")
    }

}, [zip, city, country, state, country])

return (
    <TransactConsumer>
        {({ userSave, getFormApi, formFunction, formStart }) => {

            return (
                <Fragment>
                    {title && <Grid item xs={12}>
                        <Typography variant="body1">{title}</Typography>
                    </Grid>}

                    <Grid item xs={12}>
                        <SectionField
                            title={title}
                            name={binding + ".Country"}
                            required
                            defaultValue={{ label: "United States", value: "US" }}
                            label="Country"
                            suggestions={countries}
                            component={MuiReactSelect}
                        />
                    </Grid>
                    <Grid item xs={12}>
                        <SectionField
                            title={title}
                            name={binding + ".Address1"}
                            required
                            label="Address Line 1"
                            fullWidth
                            component={TextField}
                        />
                    </Grid>
                    <Grid item xs={12}>
                        <SectionField
                            title={title}
                            name={binding + ".Address2"}
                            label="Address Line 2"
                            fullWidth
                            component={TextField}
                        />
                    </Grid>
                    <Grid item xs={12} sm={6}>
                        <SectionField
                            title={title}
                            name={binding + ".City"}
                            required
                            label="City"
                            fullWidth
                            component={TextField}
                        />
                    </Grid>
                    <Grid item xs={12} sm={4}>
                        <SectionField
                            title={title}
                            name={binding + ".State"}
                            required
                            label={isUsCountry() ? "State" : isCaCountry() ? "Province" : "State / Province"}
                            fullWidth
                            component={ MuiReactSelect}
                        />
                    </Grid>
                    <Grid item xs={12} sm={2}>
                        <SectionField
                            title={title}
                            name={binding + ".Zip"}
                            required
                            label="Zip"
                            fullWidth
                            component={TextField}


                        />
                    </Grid>
                </Fragment >
            )
        }}
    </TransactConsumer>
)
}

   ====SectionField====
  import React, { useEffect } from 'react'
  import useSectionData from './useSectionData';
  import { Field } from 'formik';
  import PropTypes from 'prop-types';

  const SectionField = ({ children, title, name, ...rest }) => {
  const { addField } = useSectionData();

useEffect(() => {
    addField(title, name)
}, [title, name])

return (
    <Field name={name} {...rest}>
        {children}
    </Field>
)
}

SectionField.propTypes = {
title: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), 
PropTypes.node]),
  };

  export default SectionField

部分字段组件是formik字段元素的包装。    什么是确保我只能在所有电话之后才能打电话的最好方法    字段已填写。现在,它被称为    单击,比如说zip是60000,它会调用useEffect 10次

除了使用formik值来代替  作为依赖项。任何最佳做法都可能会有所帮助。谢谢。

1 个答案:

答案 0 :(得分:0)

您可以让变量保持状态,该变量指示是否已填写所有字段。您可以在当前的useEffect中设置该变量。看起来像这样:

const [ allFieldsFilled, setAllFieldsFilled ] = useState(false);

useEffect(() => {
    setAllFieldsFilled(zip && city && country && state && country) 
}, [zip, city, country, state, country])

一旦指示出字段是否全部填写完毕,您就可以再创建一个useEffect来触发验证(您可以将它们合并为一个,但是我可以认为将它们分开会使意图更清晰):

useEffect(() => {
    if(allFieldsFilled){
       performValidation();
    }
}, [zip, city, country, state, country])

要避免自己键入要触发验证的所有字段,可以执行以下操作:

const validationFields = [zip, city, country, state];
useEffect(()=>{
     //Code
}, [...validationFields])