使用Formik降档自动完成Onblur重置值



我的表单具有一个字段,需要通过API调用显示建议。应该允许用户选择是否选择其中一个选项,并且它们输入的值适用于表格提交,但是需要此字段。我正在使用formik来处理表单,yup进行表单验证以检查是否需要此字段,对自动完成的降档以及该字段的材料。

当用户决定不使用建议的选项和Onblur触发器之一时,问题就出现了。Onblur总是重置该领域,我相信这是降档引起这种行为,但是解决此问题的解决方案表明控制降档状态,当我尝试时,它与Formik和Yup无法很好地工作,并且有一些问题我可以``由于这些组件控制该字段的输入值。

到目前为止我拥有的东西:

const AddBuildingForm = props => {
    const [suggestions, setSuggestions] = useState([]);
    const { values,
        errors,
        touched,
        handleChange,
        handleBlur,
        handleSubmit, 
        modalLoading,
        setFieldValue,
        setFieldTouched,
        classes } = props;
    const loadOptions = (inputValue) => {  
        if(inputValue && inputValue.length >= 3 && inputValue.trim() !== "")
        {
            console.log('send api request', inputValue)
            LocationsAPI.autoComplete(inputValue).then(response =>  {
                let options = response.data.map(erlTO => { 
                    return {
                        label: erlTO.address.normalizedAddress,
                        value: erlTO.address.normalizedAddress
                    }
                });
                setSuggestions(options);
            });
        }
        setFieldValue('address', inputValue); // update formik address value
    }
    const handleSelectChange = (selectedItem) => {
        setFieldValue('address', selectedItem.value); // update formik address value
    }
    const handleOnBlur = (e) => {
        e.preventDefault();
        setFieldValue('address', e.target.value);
        setFieldTouched('address', true, true);
    }
    const handleStateChange = changes => {
        if (changes.hasOwnProperty('selectedItem')) {
            setFieldValue('address', changes.selectedItem)
          } else if (changes.hasOwnProperty('inputValue')) {
            setFieldValue('address', changes.inputValue);
          }
    }
    return (
        <form onSubmit={handleSubmit} autoComplete="off">
            {modalLoading && <LinearProgress/>}
            <TextField
                id="name"
                label="*Name"
                margin="normal"
                name="name"
                type="name"
                onChange={handleChange}
                value={values.name}
                onBlur={handleBlur}
                disabled={modalLoading}
                fullWidth={true}
                error={touched.name && Boolean(errors.name)}
                helperText={touched.name ? errors.name : ""}/> 
            <br/>
            <Downshift  id="address-autocomplete"
                onInputValueChange={loadOptions}
                onChange={handleSelectChange}
                itemToString={item => item ? item.value : '' }
                onStateChange={handleStateChange}
               >
                {({
                        getInputProps,
                        getItemProps,
                        getMenuProps,
                        highlightedIndex,
                        inputValue,
                        isOpen,
                    }) => (
                        <div>
                            <TextField
                                id="address"
                                label="*Address"
                                name="address"
                                type="address"
                                className={classes.autoCompleteOptions}
                                {...getInputProps( {onBlur: handleOnBlur})}
                                disabled={modalLoading}
                                error={touched.address && Boolean(errors.address)}
                                helperText={touched.address ? errors.address : ""}/>
                            <div {...getMenuProps()}>
                                {isOpen ? (
                                    <Paper className={classes.paper} square>
                                        {suggestions.map((suggestion, index) =>
                                            <MenuItem {...getItemProps({item:suggestion, index, key:suggestion.label})} component="div"  >
                                                {suggestion.value}
                                            </MenuItem>
                                        )}
                                    </Paper>
                                ) : null}
                            </div>
                        </div>
                )}                
            </Downshift>
            <Grid container direction="column" justify="center" alignItems="center">
                <Button id="saveBtn"
                        type="submit" 
                        disabled={modalLoading} 
                        className = {classes.btn}
                        color="primary" 
                        variant="contained">Save</Button>
            </Grid>
        </form>
    );
}
const AddBuildingModal = props => {
    const { modalLoading, classes, autoComplete, autoCompleteOptions } = props;
    return(
        <Formik
            initialValues={{ 
                name: '', 
                address: '',
            }}
            validationSchema={validationSchema}
            onSubmit = {
                (values) => {
                    values.parentId = props.companyId;
                    props.submitAddBuildingForm(values);
                }
            }
            render={formikProps => <AddBuildingForm 
                                        autoCompleteOptions={autoCompleteOptions}
                                        autoComplete={autoComplete} 
                                        classes={classes} 
                                        modalLoading={modalLoading}
                                        {...formikProps} />}
        />
    );
}

使它起作用。需要使用thangeouterClick并设置具有formik值的降档状态:

const handleOuterClick = (state) => {
    // Set downshift state to the updated formik value from handleOnBlur
    state.setState({
        inputValue: values.address
    })
}

现在,每当我单击时,该值就会停留在输入字段中。