我很清楚,formik不支持文件上传。我读过那里有黑客。我已经用onChange
,setFieldValue
和event.current.target
尝试了以下方法。问题在于,当选择文件时,组件将呈现,并且整个页面将变为空白。我究竟做错了什么?谢谢!
import React from 'react';
import { Formik, Form, Field } from 'formik';
const initialValues = {
file: ''
};
const TestArt = () => {
const onSubmitFile = values => {
debugger;
};
return (
<div>
<Formik
initialValues={initialValues}
onSubmit={onSubmitFile}
component={UploadFile}
/>
</div>
);
};
function UploadFile({ setFieldValue }) {
debugger;
return (
<div>
<Form>
<Field
id="file"
type="file"
name="file"
onChange={event => {
setFieldValue('file', event.currentTarget.files[0]);
}}
/>
<button>submit</button>
</Form>
</div>
);
}
export default TestArt;
我不确定您为什么认为Formik不支持文件。 Formik在状态中管理值,因此除了未设置默认Formik字段来处理这些对象外,没有其他原因不能使用文件(或任何其他类型的数据)。
根据Formik文档-https://jaredpalmer.com/formik/docs/api/field
将自动将输入连接到Formik。它使用name属性与Formik状态进行匹配。将默认为HTML元素。
这里真正的关键是如何将输入连接到Formik。您需要设置onChange属性。这将覆盖onik的Formik的默认“接线”。 Formik的默认“接线”的另一点是将HTML输入标签的值设置为等于该字段的状态值。这是您特定问题的出处,因为在使用react时,所有文件输入都必须不受控制(不受状态控制)。
根据react docs-https://reactjs.org/docs/uncontrolled-components.html#the-file-input-tag
在React中,an始终是不受控制的组件,因为其值只能由用户设置,而不能以编程方式设置。
因此,要解决此问题,您将需要制作一个带有onChange的普通HTML输入标签,以根据需要设置formik值。这个问题是因为它不受控制,所以与formik不同步。众所周知,我们无法控制文件输入,因此我们将不得不使用变通方法。人们通常要做的是隐藏他们的“真实”文件输入组件,而是渲染一个显示状态的“占位符”组件。最后,使用react Ref连接“占位符”,以便您可以与文件输入进行交互,而无需从“占位符”呈现它。
import React from "react";
import { Formik, Form } from "formik";
const initialValues = {
file: ""
};
const TestArt = () => {
const onSubmitFile = values => {
debugger;
};
return (
<div>
<Formik
initialValues={initialValues}
onSubmit={onSubmitFile}
component={UploadFile}
/>
</div>
);
};
function UploadFile({ values, setFieldValue }) {
debugger;
const fileInput = React.createRef();
return (
<div>
<Form>
<input
type="file"
style={{display: "none"}}
onChange={event => {
setFieldValue("file", event.currentTarget.files[0]);
}}
ref={fileInput}
/>
<button type="button" onClick={() => fileInput.current.click()}>
Choose file
</button>
<small>
{values.file ? values.file.name || "Error" : "No file chosen"}
</small>
<br />
<button>submit</button>
</Form>
</div>
);
}
export default TestArt;
您也可以在codesandbox-https://codesandbox.io/s/formik-file-upload-example-39orl上查看此>
现在还不错的是,您实际上可以影响此“占位符”组件的外观,因此您可以使用精美的输入按钮或其他任何东西(可以考虑使用文件对象的其他字段,例如size-https://developer.mozilla.org/en-US/docs/Web/API/File)