簡體   English   中英

react-hook-form 覆蓋 onChange function 並延遲更新值

[英]react-hook-form overwrites onChange function and updates value late

我用useStateonChange制作了一個定制的Select組件。 我嘗試將它與react-hook-form一起使用。

這是Select組件的代碼。

const Select = forwardRef<HTMLInputElement, ComponentPropsWithoutRef<"input">>((props, ref) => {
  const internalRef = useRef<HTMLInputElement>(null);
  const [fruit, setFruit] = useState("");
  const [isOpen, setIsOpen] = useState(false);

  useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(
    ref,
    () => internalRef.current,
    []
  );

  const onClickFruit = (e: React.MouseEvent<HTMLLIElement>) => {
    const fruit = e.currentTarget.textContent as string;
    setFruit(fruit);
    setIsOpen(false);
  };

  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setFruit(e.target.value);
  };

  return (
    <div>
      <div onClick={() => setIsOpen((prev) => !prev)}>
        <input 
          id="input"
          type="text"
          ref={internalValue} 
          value={fruit} 
          // problem No.1 comes from below.
          onChange={onChange} 
          {...props} 
        />
      </div>
      {isOpen && (
        <ul>
          <li onClick={onClickFruit}>apple</Li>
          <li onClick={onClickFruit}>peach</Li>
          <li onClick={onClickFruit}>grape</Li>
        </ul>
      )}
    </div>
  );
};

我在Form組件中使用了這個組件和react-hook-form ,如下所示。

interface FormValue {
  fruit: string;
}

const Form = () => {
  const {register, handleSubmit, formState: {errors}} = useForm<FormValue>({ mode: "onChange" });

  const onSubmit = (e: FieldValues) => {
    console.log(e);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Select {...register("fruit", {
          validate: (value) => value !== "peach" || "No Peach Allowed!",
        })} 
      />
      <button type="submit">submit</button>
    </form>
  );
};

問題是,

  1. {...props}出現在onChange之前時,我只能在輸入中寫入文本。 似乎react-hook-form 的 onChange覆蓋了輸入的 onChange 如果我將onChange function 作為道具發送並想讓兩個onChange函數都工作怎么辦?
  2. 當我 select蘋果並更改為桃子然后提交表單時,它會在控制台上記錄蘋果 我希望桃子被記錄下來。
  3. 當我 select peach或 write peach時,雖然我使用的是onChange模式,但不會觸發驗證。
  4. 只有在我單擊提交按鈕后才會出現錯誤消息。

我該如何解決它們? 請幫忙。

ps 我試過Controller 我可以寫,但是在提交表單時它記錄了 {fruit: undefined} 。 更糟糕的是,當我單擊li中的水果時,輸入的值沒有更新。

為了處理第一個問題(可能會解決其他問題),您需要“合並” onChange 函數。

IE


  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setFruit(e.target.value);
    if (props.onChange) {
        props.onChange(e);
    }
  };

否則只有兩個 onChange 中的一個被調用。

問題 1:為了解決這個問題,將props解構為{onChange, ...restProps}input組件僅傳遞restProps以便 RHF 的onChange不會覆蓋自定義onChange

問題 2 和 3:您需要在onChangeonClickFruit函數中調用解構的onChange ,以便 RHF 具有更新的值。 因此,這些功能可以更新如下

const onClickFruit = (e: React.MouseEvent<HTMLLIElement>) => {
    const fruit = e.currentTarget.textContent as string;
    onChange(fruit)
    setFruit(fruit);
    setIsOpen(false);
  };

  const onInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setFruit(e.target.value);
    onChange(e.target.value);
  };

並更新輸入如下

      <input 
          id="input"
          type="text"
          ref={internalValue} 
          value={fruit}
          onChange={onInputChange} 
          {...restProps} 
        />

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM