7

I have two components, first is Formik form:

<Formik
  initialValues={{files: []}}
  onSubmit={values => {
  console.log(values)}}>
    {props => (
      <form onSubmit={props.handleSubmit}>
        <UploadComponent/>
        <button type="submit"></button>
      </form>
    )}
</Formik>

Second is UploadComponent:

const UploadComponent = () => {
  const [files, setFiles] = useState([]);
  const {getRootProps, getInputProps, isDragActive} = useDropzone({
    accept: 'image/*',
    onDrop: acceptedFiles => {
      setFiles(acceptedFiles.map(file => Object.assign(file, {
        preview: URL.createObjectURL(file)
      })))
    }
  })
  return (
    <div>
      <div {...getRootProps({className: 'dropzone'})}>
        <input {...getInputProps()} />
        <p>Drag and drop some files here, or click to select files</p>
      </div>
   </div>
  )

I want to get these files as values to Formik, I added some props to UploadComponent, like

value={props.values.files}
onChange={props.handleChange}
onBlur={props.handleBlur}
name='files'

I expect to get an array of uploaded files in formik. Instead I get initial value of files (empty array). How to get these files and pass them into the formik form byreact-dropzone?

ArcMech
  • 475
  • 1
  • 5
  • 16
  • 1
    you should pass your array to Formik with setFieldValue: (field: string, value: any, shouldValidate?: boolean), Can you try this ? https://jaredpalmer.com/formik/docs/api/formik – Ozan Manav Dec 01 '19 at 18:44
  • @OzanManav I need to confess I have no idea how to implement it properly. I mean in some cases it should be something like ```onClick={e => {props.setFieldValue('example', e.target.value)```. But I don't know which event should be used in this case (dropping images into input file) – ArcMech Dec 01 '19 at 18:51
  • Tried ```onChange={e => (props.setFieldValue('files', e.currentTarget.value ))}```, doesn't work – ArcMech Dec 01 '19 at 19:18
  • Can you create codesandbox so I can help you fix it? – Tushant Feb 06 '20 at 16:02
  • make use of setFieldValue method in Formik , that will set value to your specific field and then get value from that field using on change or submit handler – Hanzla Habib Feb 16 '20 at 14:47

1 Answers1

8

You should pass Formik props setFieldValue down to UploadComponent and use it to set returned value from UploadComponent

Formik form:

 render={({ values, handleSubmit, setFieldValue }) => {
            return (
              <form onSubmit={handleSubmit}>
                <div className="form-group">
                  <label htmlFor="file">Multiple files upload</label>

                  <UploadComponent setFieldValue={setFieldValue} />//here


                   // list of uploaded files  
                  {values.files &&
                    values.files.map((file, i) => (
                      <li key={i}>
                        {`File:${file.name} Type:${file.type} Size:${
                          file.size
                        } bytes`}{" "}
                      </li>
                    ))}
                </div>
                <button type="submit" className="btn btn-primary">
                  submit
                </button>
              </form>


UploadComponent:

 const UploadComponent = props => {
  const { setFieldValue } = props;
  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    accept: "image/*",
    onDrop: acceptedFiles => {
      setFieldValue("files", acceptedFiles);
    }
  });
  return (
            .
            .
            .


sample codesansbox,Hope be helpful

Alex
  • 3,941
  • 1
  • 17
  • 24
  • Is there an option to keep the previous files? Normally you would do `setFiles((files) => [...files, ...acceptedFiles])`. Otherwise the previous data is always deleted. – MapMyMind Dec 15 '21 at 14:29