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
};
我有一个带有自定义文件输入的表单。我正在使用反应挂钩形式。在过去,我已经能够隐藏默认 <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
};