網站搜尋

javascript - 在 React TS 中對來自 'reactstrap' 的 欄位應用自訂驗證時舊值重新出現


我在使用 React TS 時遇到舊值重新出現的問題。我先提供我的程式碼,這樣你也可以檢查它:

 const initialState = {
        name: '',
      };

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

這裡是我為輸入欄位自訂實作的驗證呼叫以及驗證內容:

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

onChange 監聽器的實作方式:

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

通用輸入驗證:

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;

現在是 ValidatedInput 欄位的實作:

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;

以及導航實作:

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

現在當一切完成並在頁面中調用 ValidatedInput,並保存一次值(發生在 onNextClick 時),然後返回到我從請求存儲獲取值的頁面,我在輸入欄中看到的值完全正常。現在當我想刪除輸入(只是為了觸發驗證)並點擊下一步時——驗證被觸發,這是可以的,但欄位中的值返回到舊的值,而不是保留新的並顯示該欄位不正確。

範例:

欄位的值為:"test123" 我將其更改為:"" 點擊下一步按鈕時會觸發驗證,結果不是保持值為 "",而是返回 "test123"

有什麼方法可以修好它嗎?

答案#1

你能建立一個程式碼沙盒來展示你的問題嗎?我猜問題可能來自你修改 formData 的方式,我以前在更改物件屬性時也遇到過類似的問題。也許可以嘗試將 initialState 移到組件外,並用 console.log registered.name 來查看它是否有你需要的數據?目前,我從你的程式碼獲得的信息不多,所以我不確定你是否不小心錯誤地修改或重新指派了它。另外,對於 Input 組件的建議,我認為你應該保持 key 穩定,使用 key={props.id + errors.length} 可能會導致你的組件出現一些不必要的重新渲染。