从响应接收到值后,React模态表单值不会更新

时间:2019-12-07 23:28:40

标签: javascript reactjs react-hooks

我遇到了一个问题,如果不正确使用钩子,可能是一个问题。 主要问题是,当再次关闭并打开模式时,表单内的值会更新。我找不到解决方法。首先,我以为我可能在条件循环或某些循环中使用了钩子,但事实并非如此,使用钩子规则一切正常。可能是一个小错误,但实际上我无法解决

const CustomModal = ({
    isOpen,
    toggleModal = () => {},
    modalHeader = null,
    modalBodyItems = [],
    buttonText = '',
    clearValues = () => {},
    handleSaveValues = () => {},
    confirmModal = false,
    values = {},
    handleConfirmAction = () => {},
}) => {
    console.log(values, 'values');
    let initialValues = {};
    modalBodyItems.forEach(it=> {
        initialValues[it.inputName] = values[it.inputName] || '';
    });
    console.log(initialValues, 'initialValues');
    const [errors, setErrors] = useState({});
    const {inputs, handleFieldChange, initializeFields} = useForm(() => {}, initialValues);
    console.log(errors, 'errors');
    console.log(inputs, 'inputsssssssssss');
    return (
        <Modal
            isOpen={isOpen}
            onRequestClose={() => {
                clearValues();
                toggleModal(v=>!v);
                initializeFields();
            }}
        >       <span onClick={() => {
                    clearValues();
                    initializeFields();
                    toggleModal((v) => !v);
                }}
                className='close-icon'></span>
                <header className='modal-header'>{modalHeader}</header>
                <div className='modal-body'>
                    {modalBodyItems.map((item, id) => {
                        return (
                            <div key={id} className={classNames('modal-body__item', {
                                'modal-body__item--error' : errors[item.inputName],
                            })}>
                                <span>{item.name}</span>
                                <InputWithValidation
                                    type={item.type || 'text'}
                                    name={item.inputName}
                                    placeholder={item.name}
                                    value={inputs[item.inputName]}
                                    errorClassName='form-input__error'
                                    className='form-input__input'
                                    wrapperClassName='form-input--search'
                                    onChange={(e) => {
                                        setErrors({});
                                        handleFieldChange(e);
                                    }}
                                    errorMessage={errors[item.inputName]}
                                />
                            </div>
                        );
                    })}
                </div>
                <footer className='modal-footer'>
                    <Button
                        className='btn--violet'
                        text={buttonText}
                        attrs={{style : {width: 'auto'}}}
                        onClick={() => {
                            if (!confirmModal) {
                                const errors = formValidator(inputs);

                                if (!isEmpty(errors)) {
                                    setErrors(errors);
                                    return;
                                }
                                clearValues();
                                initializeFields();
                                handleSaveValues(inputs);
                            } else {
                                handleConfirmAction();
                            }
                            toggleModal(v=>!v);
                        }}
                    />
                </footer>
        </Modal>
    );
};

export default CustomModal;

这是我的Modal组件,它使用 react-modal

这是useForm自定义钩子

import {useState} from 'react';
import {useDispatch} from 'react-redux';
import {isEmpty} from 'lodash';
import {formValidator} from '../validators/validator';

const RADIO_BUTTONS = ['CyrillicOnly', 'LatinOnly', 'DigitOnly'];

const useForm = (action, initialValues = {}) => {
    console.log('use-form');
    const dispatch = useDispatch();
    console.log(initialValues, 'initialValues inside useForm');
    const [inputs, setInputs] = useState(initialValues);
    const [errors, setErrors] = useState({});
    console.log(errors, 'errors');
    const [isInitialized, setIsInitialized] = useState(true);
    console.log(inputs, 'inputs inside useForm');
    console.log(isInitialized, 'isInitialized');
    const setInputFields = ({name, value, type, checked}) => {
        if (type === 'text' || type === 'textarea' || type === 'password' || type === 'search') {
            setInputs(inputs => ({...inputs, [name]: value}));
        } else if (type === 'checkbox') {
            setInputs(inputs => ({...inputs, [name]: checked}));
        } else if (type === 'select') {
            setInputs(inputs => ({...inputs, [name]: value}));
        } else if (type === 'radio') {
            setInputs(inputs => {
                const falsyRadioButtons  = RADIO_BUTTONS.filter(r => r !== name);
                falsyRadioButtons.forEach(r => {
                    inputs[r] = false;
                });

                return ({...inputs, [name]: checked});
            });
        } else {
            setInputs(inputs => ({...inputs, [name]: value}));
        }
    };

    const handleSubmit = (e) => {
        if (e) {
            e.preventDefault();
            e.stopPropagation();
        }

        const errors = formValidator(inputs);

        if (!isEmpty(errors)) {
            setErrors(errors);
            return false;
        }
        dispatch(action(inputs));
    };

    const initializeFields = (values) => {
        console.log('initialize fields');
        const newValues = isEmpty(values) ? initialValues : values;
        setInputs(newValues);
        setIsInitialized(true);
    };

    const handleFieldChange = (e, {startDate, endDate} = {}) => {
        if (e) {
            setErrors({});
            e && e.persist && e.persist();
            const {type, checked, value, name, title} = e.target || {};
            setInputFields({name, value, type, checked, title});
        } else {
            setInputs(inputs => ({...inputs, 'startDate': startDate}));
            setInputs(inputs => ({...inputs, 'endDate': endDate}));
        }
    };

    return {
        handleSubmit,
        handleFieldChange,
        inputs,
        errors,
        initializeFields,
        isInitialized,
    };
};

export default useForm;

0 个答案:

没有答案