dorkycam
dorkycam

Reputation: 529

File input not updating state correctly React?

Ok so I have a form that has file inputs on it for images (and it previews the image before submission) but only the first input updates (no matter which input I use to put my image up).

Here are the repro steps:

  1. Click "Add Question" button 2 or more times
  2. Click (because drop doesn't work yet) on the second dropzone and upload a file.
  3. See that the first dropzone updates and not the second

Here's a CodeSandbox for it.

And here is my code for the drop zone component:

class DropZone extends Component {

    constructor(props){
      super(props)
      this.state = {
        file: "",
        fileId: uuid()
      }
      this.handleChange = this.handleChange.bind(this)

    }

    handleChange(event) {
      this.setState({
        file: URL.createObjectURL(event.target.files[0])
      })
      //document.getElementsByClassName("dropZone").style.backgroundImage = 'url(' + this.state.file + ')';
    }

  render() {
    return (
      <div >
        <input type="file" id="file" name="file" class="inputFile" onChange={this.handleChange}/>
        <label  key={uuid()} for="file" value={this.state.file} onchange={this.handleChange}>
          <div class="dropZone" key={uuid()}>
            Drop or Choose File
            <img src={this.state.file} id="pic" name="file" accept="image/*"/>
          </div>
        </label>
        <div>
      </div>
      </div>
    );
  }
}

I am new to React and JS so any explanation would help loads. Thanks!

Upvotes: 0

Views: 2270

Answers (1)

Anshul Bansal
Anshul Bansal

Reputation: 1893

It is not an issue with React but with HTML bindings. You need to provide a unique id to the input box and the label htmlFor attribute. I have updated the code below. and your code sandbox here -> https://codesandbox.io/s/kkj7j61noo

class DropZone extends Component {

    constructor(props){
      super(props)
      this.state = {
        file: "",
        fileId: uuid()
      }
      this.handleChange = this.handleChange.bind(this)

    }

    handleChange(event) {
      this.setState({
        file: URL.createObjectURL(event.target.files[0])
      })
      //document.getElementsByClassName("dropZone").style.backgroundImage = 'url(' + this.state.file + ')';
    }

  render() {
    const uniqueId = this.state.fileId;
    return (
      <div >
        <input type="file" id={uniqueId} name={uniqueId} class="inputFile" onChange={this.handleChange}/>
        <label  key={uuid()} htmlFor={uniqueId} value={this.state.file}>
          <div class="dropZone" key={uuid()}>
            Drop or Choose File
            <img src={this.state.file} id="pic" name="file" accept="image/*"/>
          </div>
        </label>
        <div>
      </div>
      </div>
    );
  }
}

Upvotes: 3

Related Questions