使用 react-hook-form 上传和保存文件列表
Upload and save list of files with react-hook-form
我正在构建一个主要针对使用 Ionic React
的浏览器的网站。
我正在尝试使用 react-hook-form
上传文件列表(以及其他数据)并将它们与其他数据一起保存在 FieldArray 中。
我已经在 answer in Ionic Forum 之后使用 IonButton 和输入实现了文件上传。
<input
type="file"
id="file-upload"
style={{ display: "none" }}
onChange={() => { setFile(index);}}/>
<IonButton
onClick={() => {openFileDialog();}}
disabled={files === undefined || files[index] === undefined}>
<IonLabel>Upload file</IonLabel>
<IonIcon slot="start" />
</IonButton>
代码:
function openFileDialog() {
(document as any).getElementById("file-upload").click();
}
const setFile = (index: number) => (_event: any) => {
console.log(`Getting file for index ${index}`);
let f = _event.target.files![0];
var reader = new FileReader();
reader.onload = function () {
setValue(`files.${index}.file`, reader.result);
};
reader.onerror = function () {
console.log("File load failed");
};
reader.readAsDataURL(f);
};
完整示例代码:codesandbox
文件已正确上传,但我无法将其添加到 FieldArray 中的正确字段。文件总是添加到元素 0。我假设这与未在表单中直接修改但在函数 openFileDialog() 中修改的输入有关。结果,input 的 onChange() 函数没有收到正确的 index 值。
是否存在其他错误来源?
一个解决方案是在 IonButton 的 onClick() 方法中等待文件加载,但是在调用 (document as any).getElementById("file-upload").click();
.
时我无法发送索引
另一种解决方案可能是只使用一个组件而不是两个组件来上传文件。但是,Ionic 似乎没有这方面的组件。 IonInput type="file" 不起作用。 documentation 令人困惑:“文件”没有出现在 属性 类型的可接受值列表中,但在属性 multiple 和 accepted 的描述中提到了它。
如何正确保存文件?
我发现您的方法存在一些问题,我还删除了将文件读取到 blob 中的操作,在用户实际提交之前您不应该这样做,因为他们可能会删除文件。
第一期 - 您没有将索引传递给此函数
const setFile = (index: number, _event: any) => {
methods.setValue(`files[${index}].file` as any, _event.target.files[0]);
methods.setValue(
`files[${index}].title` as any,
_event.target.files[0]?.name
);
};
第二个问题,您没有为上传按钮创建唯一标识符,您还需要在那里包含索引
<IonItem>
<input
type="file"
id={`file-upload-${index}`} // <== NEW CODE
style={{ display: "none" }}
onChange={(e) => {
console.log("In input", index);
setFile(index, e);
}}
/>
<IonButton
onClick={() => {
openFileDialog(index); // <== NEW CODE
}}
disabled={files === undefined || files[index] === undefined}
>
<IonLabel>Upload file</IonLabel>
<IonIcon slot="start" />
</IonButton>
</IonItem>
然后您需要 openFileDialog
中的索引,以便您可以单击相应的按钮。
function openFileDialog(index: any) {
(document as any).getElementById("file-upload-" + index).click();
}
在此沙箱中查看完整的解决方案
我正在构建一个主要针对使用 Ionic React
的浏览器的网站。
我正在尝试使用 react-hook-form
上传文件列表(以及其他数据)并将它们与其他数据一起保存在 FieldArray 中。
我已经在 answer in Ionic Forum 之后使用 IonButton 和输入实现了文件上传。
<input
type="file"
id="file-upload"
style={{ display: "none" }}
onChange={() => { setFile(index);}}/>
<IonButton
onClick={() => {openFileDialog();}}
disabled={files === undefined || files[index] === undefined}>
<IonLabel>Upload file</IonLabel>
<IonIcon slot="start" />
</IonButton>
代码:
function openFileDialog() {
(document as any).getElementById("file-upload").click();
}
const setFile = (index: number) => (_event: any) => {
console.log(`Getting file for index ${index}`);
let f = _event.target.files![0];
var reader = new FileReader();
reader.onload = function () {
setValue(`files.${index}.file`, reader.result);
};
reader.onerror = function () {
console.log("File load failed");
};
reader.readAsDataURL(f);
};
完整示例代码:codesandbox
文件已正确上传,但我无法将其添加到 FieldArray 中的正确字段。文件总是添加到元素 0。我假设这与未在表单中直接修改但在函数 openFileDialog() 中修改的输入有关。结果,input 的 onChange() 函数没有收到正确的 index 值。 是否存在其他错误来源?
一个解决方案是在 IonButton 的 onClick() 方法中等待文件加载,但是在调用 (document as any).getElementById("file-upload").click();
.
另一种解决方案可能是只使用一个组件而不是两个组件来上传文件。但是,Ionic 似乎没有这方面的组件。 IonInput type="file" 不起作用。 documentation 令人困惑:“文件”没有出现在 属性 类型的可接受值列表中,但在属性 multiple 和 accepted 的描述中提到了它。
如何正确保存文件?
我发现您的方法存在一些问题,我还删除了将文件读取到 blob 中的操作,在用户实际提交之前您不应该这样做,因为他们可能会删除文件。
第一期 - 您没有将索引传递给此函数
const setFile = (index: number, _event: any) => {
methods.setValue(`files[${index}].file` as any, _event.target.files[0]);
methods.setValue(
`files[${index}].title` as any,
_event.target.files[0]?.name
);
};
第二个问题,您没有为上传按钮创建唯一标识符,您还需要在那里包含索引
<IonItem>
<input
type="file"
id={`file-upload-${index}`} // <== NEW CODE
style={{ display: "none" }}
onChange={(e) => {
console.log("In input", index);
setFile(index, e);
}}
/>
<IonButton
onClick={() => {
openFileDialog(index); // <== NEW CODE
}}
disabled={files === undefined || files[index] === undefined}
>
<IonLabel>Upload file</IonLabel>
<IonIcon slot="start" />
</IonButton>
</IonItem>
然后您需要 openFileDialog
中的索引,以便您可以单击相应的按钮。
function openFileDialog(index: any) {
(document as any).getElementById("file-upload-" + index).click();
}
在此沙箱中查看完整的解决方案