I am not sure why you think Formik doesn't support files. Formik manages values in state so there is no specific reason you can't use files (or any other type of data) other than that the default Formik field isn't setup to handle these objects.
According to the Formik docs - https://jaredpalmer.com/formik/docs/api/field
will automagically hook up inputs to Formik. It uses the name attribute to match up with Formik state. will default to an HTML element.
What is really key here is how the inputs are hooked up to Formik. In your case you are setting the onChange prop. This will override the default "wiring" of Formik for onChange. Another bit of the default "wiring" of formik is to set the HTML input tag's value equal to the state value for that field. This is where your particular issue is coming from because when using react all file inputs must be uncontrolled (not controlled by state).
According to the react docs - https://reactjs.org/docs/uncontrolled-components.html#the-file-input-tag
In React, an is always an uncontrolled component because its value can only be set by a user, and not programmatically.
So to solve this you will want to make a normal HTML input tag with the onChange wired to set the formik value as you desire. The issue with this is as it is uncontrolled it is not in sync with formik. As we already know, we cannot control file inputs so we will have to use a work around. What people typically do is hide their "real" file input component and instead render a "placeholder" component that displays the state. Finally the "placeholder" is wired up using react Ref so that you can interact with the file input without it being rendered from the "placeholder".
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;
You can also look at this on codesandbox - https://codesandbox.io/s/formik-file-upload-example-39orl
What is also nice now is that you can actually influence how this "placeholder" component looks so you can have fancy input button or whatever (can consider using the file objects other fields such as size - https://developer.mozilla.org/en-US/docs/Web/API/File)