-2

How do you change state inside a function ?

I'm trying to change the state of selectedFile from null to the event.target.files[0] but it's not working inside the onChangeHandler function.

import React, { Component } from "react";

export default class Comp1 extends Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedFile: null,
    };
  }

  onChangeHandler = event => {
    console.log(event.target.files[0]);   // <--THIS WORKS //
    console.log(this.state.selectedFile); // <-- THIS WORKS //
    this.setState({
      selectedFile: event.target.files[0]
    }); // THIS DOES NOT WORK //
    console.log(this.state.selectedFile); // selectedFile did not update state //

  };
  render() {
    return (
      <div className="ui placeholder segment">
        <div className="ui icon header" />
        <input
          type="file"
          className="file"
          id="file"
          onChange={this.onChangeHandler}
        />
        <label htmlFor="file">
          <div className="button">Press</div>
        </label>
      </div>
    );
  }
}
Community
  • 1
  • 1
Jay
  • 185
  • 15
  • 1
    `setState` is not synchronous, but you can pass a callback to it. – Federkun Aug 21 '19 at 21:18
  • If you move the console.log of `this.state.selectedFile` in `render`, then does it show as being updated, or how are you verifying that the state update didn't work? Because `setState` is asynchronous, the `console.log(this.state.x)` that you put right after it will be run immediately, so although the state hasn't updated yet at the time of the printing, that doesn't mean that it's not updating the state. – AnnieP Aug 21 '19 at 21:36

2 Answers2

2

If you'd like to read your new state or update another state item based on the new state, you could provide a callback to the setState function that will run when your state updates:

onChangeHandler = (event) => {
  this.setState({
    selectedFile: event.target.files[0]
  }, () => {
    // `selectedFile` will have an updated value
    console.log(this.state.selectedFile)

    // if needed, update your state again based on the new state
    this.setState({ ... })
  })
}
goto
  • 4,336
  • 15
  • 20
  • What specifically did not work? The state wasn't updated inside of the callback? – goto Aug 21 '19 at 21:30
  • Sorry this actually did work, it's just I had a second function outside of this.setState so it called that second function before I could console.log.......it was a mess but I fixed it. Thanks All – Jay Aug 21 '19 at 21:38
-1

i think this

onChange={this.onChangeHandler}

change to bind the this, needs to be:

onChange={this.onChangeHandler.bind(this)}

or start using hooks, i see your component can be migrated from class to functional approach

asotog
  • 225
  • 2
  • 8