1

I am trying to hook up a dropzone component with redux form but to no avail. When my form is submitted, and the MyFormReview component is rendered, the formValues in the Redux store doesn't seem to hold the files and so are not rendered. I have looked for similar posts but can't see where I am going wrong. Thank you in advance for any help and if you need more info please let me know!

I have not included the code for the parent form component as it just renders between MyForm and MyFormReview.

Many thanks in advance.

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { reduxForm, Field } from 'redux-form';
import Dropzone from './Dropzone';

class MyForm extends Component {

    render() {
        return (
            <form onSubmit={this.props.handleSubmit(this.props.onFormSubmit)} >
               <div className="flex flex-column">
                  <div className="flex center w-50 mb2">
                      <Field
                      name="files"
                      component={Dropzone}
                  />
               </div>
                    <div>
                        <Link to="/dashboard">
                            <Button>Cancel</Button>
                        </Link>
                        <button primary type="submit">
                            Review
                        </button>
                    </div>
                </div>
            </form>
       );
    }
};

export default reduxForm({
    validate,
    form: 'myForm',
    destroyOnUnmount: false
})(MyForm);

The onFormSubmit prop is used to switch between a review and edit render of the form (so user can confirm his/her inputs) onFormSubmit={() => this.setState({ showFormReview: true})}

And here is the Dropzone component:

import React, {Component} from 'react';
import {DropzoneArea} from 'material-ui-dropzone';

class Dropzone extends Component{
  constructor(props){
    super(props);
    this.state = {
      files: []
    };

  }
  handleChange(files){
    this.setState({
      files: files
    });
  }
  render(){
    return (
      <DropzoneArea 
        acceptedFiles = {['image/*']}
        filesLimit = {10}
        dropzoneText="upload your images here!"
        onChange={this.handleChange.bind(this)}
        />
    )  
  }
} 

export default Dropzone;

Here is the MyFormReview component:

const MyFormReview = ({ onCancel, formValues, submitForm, history }) => {
    const reviewFields = () => {
            return (
            <div className="ba1 ma1" key={"files"}>
                <label>"Files"</label>
                <div>{formValues["files"]}</div>
            </div>
        )
    });

    return (
        <div>
            <h3>Please confirm your entries</h3>    
            {reviewFields}
            <button className = "yellow darken-3  white-text btn-flat" onClick={onCancel}>
                Back
            </button>
            <button
                className = "green white-text right btn-flat" 
                onClick={() => submitForm(formValues, history)}
            >
                Send Survey
            </button>
        </div>
    );
};

function mapStateToProps(state) {
    return {formValues: state.form.myForm.values};
}

export default connect(mapStateToProps, actions)(withRouter(MyFormReview));

1 Answer 1

1

For anyone who stumbles across this post, here is my solution:

In Dropzone component, handleChange becomes:

handleChange(files){
    this.setState({
      files: files
    });
    this.props.input.onChange(files)
}

and in myFormReview, I can preview the image with the following if statement inserted into the reviewFields function.

const reviewFields = _.map(formFields,  ({name, label}) => {
            if(name === "files"){
                return <div>{_.map(formValues[name], (file) => <img alt={file.name} src={URL.createObjectURL(file)} /> )}</div>
            }
            else{
                return (
                    <div className="ba1 ma1" key={name}>
                        <label>{label}</label>
                        <div>{formValues[name]}</div>
                    </div>
                )
            }
    });
1
  • why do you need to manage files in 2 places (state and props)? handleChange(files){this.props.input.onChange(files);} works also Commented Apr 2, 2022 at 7:21

Not the answer you're looking for? Browse other questions tagged or ask your own question.