javascript - Gamle verdier dukker opp igjen i React TS når man bruker tilpasset validering på <Input>-felt fra 'reactstrap'


Jeg har problemer med at gamle verdier dukker opp igjen i React TS. Jeg gir først koden min slik at du kan sjekke den også:

 const initialState = {
        name: '',
      };

  const [registeredValidations, setRegisteredValidations] = useState({} as RegisteredValidationMap);
      const [formData, setFormData] = useState({
        ...initialState,
        name: requestStore.formData.name[0] || initialState.name
      });
      

Og her er kallet til min spesialimplementerte validering for inndatafeltet og valideringen:

      <ValidatedInput
        name="name"
        value={formData.name}
        onChange={handleOnChange}
        validations={[GenericInputValidation]}
        isOptional={!fieldsRequired}
        setRegisteredValidations={setRegisteredValidations}
        registeredValidations={registeredValidations}
      />
   <Row>
        <Navigation handleOnNextClick={handleOnNextClick} registeredValidations={registeredValidations} />
      </Row>

implementeringen av onChange-lytter:

  const handleOnChange = (e: ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    
    setFormData(prevState => ({
      ...prevState,
      [name]: value,
    }));
  };

den generiske inputvalideringen:

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;

og nå implementeringen av ValidatedInput-feltet:

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;

og implementeringen av navigasjonen:

    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>
  );

Nå når alt er gjort og jeg kaller ValidatedInput på en side, og lagrer verdiene en gang (som skjer på onNextClick), så når jeg går tilbake til den siden får jeg verdiene fra request-lageret vist i inputfeltet, noe som er helt fint. Og nå når jeg vil fjerne inputen (bare for å utløse valideringen) og klikker neste - valideringen blir utløst, noe som er ok, men verdien i feltet går tilbake til den gamle i stedet for å beholde den nye og vise at dette feltet er feil.

Eksempel :

Feltet har verdi: "test123" Jeg endrer til: "" Å klikke på Neste-knappen utløser valideringen, og i stedet for å beholde verdien som "" returnerer den "test123"

Noen ideer om hvordan man fikser det?

Svar #1

Kan du lage en kode-sandbox for å vise problemet ditt? Jeg antar at problemet kommer fra måten du endrer formData på, jeg pleide å få et lignende problem når jeg endret eiendommer på et objekt. Kanskje prøv å flytte initialState ut av komponenten og bruk console.log registered.name for å se om det har dataene du trenger? For nå har jeg ikke mye informasjon fra koden din, så jeg er ikke sikker på om du ved et uhell har endret/tilordnet det feil. Også, et forslag for Input-komponenten er at jeg tror du bør holde key stabil, key={props.id + errors.length} å bruke dette kan få komponenten din til å få noen unødvendige re-renderinger.