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