useForm隐藏的嵌套文件输入不起作用

useForm hidden nested file input not working

我有一个带有自定义文件输入的表单。我正在使用反应挂钩形式。在过去,我已经能够隐藏默认 <input type="file"/> 并添加我自己的自定义按钮,以 ref.current.click 为目标输入并从那里触发 onChange 事件。

然而,在尝试使用 react-hook-form 时,它似乎并不那么直接。我的印象是我必须使用 useForm 中的 Controller 组件,但我似乎无法让它工作。

目前,当我单击“添加图像”按钮时,它不会提示我选择文件。

const ImageInput = () => {
  const [selectedImage, setSelectedImage] = useState();

  const pickImageHandler = async () => {
    //I dont know what to ref here??
    ref.current.click();
  };

  const imageChange = (e) => {
    console.log("imageChange onChange triggered");
    if (e.target.files && e.target.files.length > 0) {
      setSelectedImage(e.target.files[0]);
    }
  };

  <>
    <Controller
      control={control}
      render={({ field }) => (
        <input
          control={control}
          type="file"
          accept=".jpg,.png,.jpeg"
          style={{ display: "none" }}
          onChange={imageChange}
          {...field}
        />
      )}
    />
    <Button
      type="button"
      variant="contained"
      className={classes.pickImageButton}
      onClick={pickImageHandler}
    >
      Add Image
    </Button>
  </>;
}; 

 const PostForm = (props) => {
    const submitFunction= async (data) => {
      //handle submitForm with formData
    }
    <form onSubmit={submitFunction}>
      <FormProvider {...methods}>
        <ImageInput {...register("cardImage")} name="cardImage" />
      </FormProvider>
      <Button type="submit" className={classes.postButton}>
        Post
      </Button>
    <form/>;
 };

你的代码中有多个错误,我已经修复了所有错误以及下面的代码。因为 register() returns 设置了一个包含输入 ref 回调的道具,你需要创建一个包装器 ref 回调来初始化 RHF ref 和你自己的 ref:

const { ref, ...fields } = register('cardImage');
const inputRef = React.useRef(); // your ref to call click() imperatively
const ImageInput = () => {
  const { register } = useFormContext();
  const { ref, ...fields } = register('cardImage');
  const inputRef = React.useRef();
  const pickImageHandler = () => {
    inputRef.current?.click();
  };

  return (
    <>
      <input
        type="file"
        accept=".jpg,.png,.jpeg"
        style={{ display: 'none' }}
        {...fields}
        ref={(instance) => {
          ref(instance); // RHF wants a reference to this input
          inputRef.current = instance; // We also need it to manipulate the elemnent
        }}
      />
      <Button type="button" variant="contained" onClick={pickImageHandler}>
        Add Image
      </Button>
    </>
  );
};

如果你只想提交一张图片你可以在用户提交后处理:

const onSubmit = (data) => {
  if (data.cardImage && data.cardImage.length > 0) {
    data.cardImage = data.cardImage[0];
  }

  console.log(data);
  // submit the data
};