I’m having issue with re-appearing old values in React TS. I’m initially providing my code so you can check it as well:
const initialState = {
name: '',
};
const [registeredValidations, setRegisteredValidations] = useState({} as RegisteredValidationMap);
const [formData, setFormData] = useState({
...initialState,
name: requestStore.formData.name[0] || initialState.name
});
And here is the call of my custom implemented validation for input field and the validation:
<ValidatedInput
name="name"
value={formData.name}
onChange={handleOnChange}
validations={[GenericInputValidation]}
isOptional={!fieldsRequired}
setRegisteredValidations={setRegisteredValidations}
registeredValidations={registeredValidations}
/>
<Row>
<Navigation handleOnNextClick={handleOnNextClick} registeredValidations={registeredValidations} />
</Row>
the onChange listener implementation:
const handleOnChange = (e: ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setFormData(prevState => ({
...prevState,
[name]: value,
}));
};
the GenericInputValidation:
export class GenericInputValidation extends Validation {
// eslint-disable-next-line @typescript-eslint/require-await
static async validate(props: ValidationProps): Promise<string[]> {
const errors = [];
if (props.newValue === '' && !props.isOptional) {
errors.push(translate('error.missing-value'));
}
return errors;
}
}
export default GenericInputValidation;
and now the ValidatedInput field implementation:
export const ValidatedInput = (props: ValidatedInputProps) => {
const [errors, setErrors] = useState([...(props.externalErrors || [])]);
const errorMessages = filterMessagesByType(errors, ERROR_TEMPLATES) || [];
const warningMessages = filterMessagesByType(errors, WARNING_TEMPLATES) || [];
let css = '';
if(errorMessages.length !== 0){
css= 'validation-failed'
}else if(warningMessages.length !== 0){
css = 'validation-warning'
}
const DOMprops = getDomProps(props);
registerValidationComponent(props, errorMessages.length > 0 ? errorMessages : warningMessages, setErrors);
return (
<div>
<Input
{...DOMprops}
onBlur={e => {
generateBlur<HTMLInputElement>(props, errors, setErrors)(e);
}}
id={props.id || props.name}
className={css}
key={props.id + errors.length}
readOnly={props.readOnly}
type={props.type}
maxLength={props.maxLength}
/>
{errors.length !== 0 && (
<Tooltip anchorSelect={`#${props.id || props.name}`} place="top">
{getErrorsForTooltip(errors)}
</Tooltip>
)}
</div>
);
};
export default ValidatedInput;
and the Navigation implementation:
const navigate = useNavigate();
const dispatch = useDispatch();
const defaultBack = () => {
navigate(-1);
};
const [warningAcknowledged, setWarningAcknowledged] = useState(false);
const handleBackClick = () => {
dispatch(setWarningsAcknowledged(false));
setWarningAcknowledged(false);
if (props.handleOnBackClick) {
props.handleOnBackClick();
} else {
defaultBack();
}
};
useEffect(() => {
setWarningAcknowledged(false);
}, [JSON.stringify(props.registeredValidations)]);
const nextFunction = async () => {
const foundErrors = [];
for (const registered of Object.values(props.registeredValidations)) {
const { value, validations, customValidations, errors, setErrors } = registered;
const validationProps: ValidationProps = {
name: registered.name,
newValue: value,
validations,
customValidations,
errors,
setErrors,
isOptional: registered.isOptional,
maxLength: registered.maxLength,
};
foundErrors.push(...(await runValidations(validationProps)));
}
const errorMessages = filterMessagesByType(foundErrors, ERROR_TEMPLATES);
const warningMessagesFiltered = filterMessagesByType(foundErrors, WARNING_TEMPLATES);
const infoMessages = filterMessagesByType(foundErrors, INFO_TEMPLATES);
const hintMessages = filterMessagesByType(foundErrors, HINT_TEMPLATES);
const warningMessagesAndInfo = warningMessagesFiltered.concat(infoMessages);
const warningMessages = warningMessagesAndInfo.concat(hintMessages);
if (errorMessages.length > 0) {
return;
} else if (warningMessages.length > 0 && !warningAcknowledged) {
setWarningAcknowledged(true);
return;
}
props.handleOnNextClick();
return (
<Container className="mt-4">
<Row>
<Col xs={6}>
{!props.hideBack && (
<Button name={'zurück' + (props.nameSuffix || '')} id={'back-button' + (props.nameSuffix || '')} onClick={handleBackClick}>
<FontAwesomeIcon icon={faArrowLeft}></FontAwesomeIcon> <Translate contentKey="generic.back" />
</Button>
)}
</Col>
<Col xs={6} className="next-button-col">
{!props.hideNext && (
<Button
name={'weiter' + (props.nameSuffix || '')}
id={'next-button' + (props.nameSuffix || '')}
onClick={() => {
nextFunction();
}}
>
<Translate contentKey="generic.next" /> <FontAwesomeIcon icon={faArrowRight}></FontAwesomeIcon>
</Button>
)}
</Col>
</Row>
</Container>
);
Now when everything is done and call the ValidatedInput in a page, and save the values ones(which happens onNextClick) then go back on that page I got the values from the request store shown in the Input field which is prefectly fine.And now when I want to remove the input(just for triggering the validation) and click next – the validation is triggered which is ok, but the value in the field returns the old one, instead to hold on the new one and show that this field is incorrect.
Example:
Field has value: “test123”
I change to: “”
Clicking Next button triggers the validation and instead of staying the value to “” it returns the “test123”
Any ideas how to fix it ?