input's event.target is null within this.setState [React.js]

前端 未结 5 1846
暖寄归人
暖寄归人 2020-12-17 09:42

In my react component I have a file input:

` 

and my onFileChan

相关标签:
5条回答
  • 2020-12-17 10:16

    class Example extends React.Component {
    
      onFileChange = e => {
        let file = e.target.files[0];
        this.setState(() => ({ file: file }));
      }
      render() {
        return <input type="file" onChange={this.onFileChange} />;
      }
    }
    
    ReactDOM.render(
      <Example />,
      document.getElementById('root')
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    
    <div id="root">
    </div>

    0 讨论(0)
  • 2020-12-17 10:18

    What is the reason for calling setState with callback ? this.setState({ file: e.target.files[0] }) should do the job.

    In your code you are referring to a synthetic event object which no longer holds information about the original DOM event. React reuses the event objects for performance reasons.

    Alternatively you can use:

    let file = e.target.files[0]; const files = e.target.files this.setState(() => ({ file: files[0] })); //doesnt work

    0 讨论(0)
  • 2020-12-17 10:19

    React uses event pooling, you can read more about it in the docs here https://reactjs.org/docs/events.html

    setState is an asynchronous function

    this.setState(() => ({ file })); // is correct
    
    0 讨论(0)
  • 2020-12-17 10:22

    Very simple/basic example to do the same task:

    class Hello extends React.Component {
        constructor(props) {
        super(props);
        this.state = {
        file: ''
        };
      }
    
      render() {
        return <div>
        <input type='file' onChange={(e) => {
        this.setState({file: e.target.files[0]}, () => {
            console.log('state', this.state);
        })
        }} />
        </div>;
      }
    }
    
    ReactDOM.render(
      <Hello name="World" />,
      document.getElementById('container')
    );
    

    I have added console log when the state will be set it will log the file details. You can see in the log when you select a file the state includes the file data.

    To see the console log you need to right click and inspect and see the Console.

    Checkout working example here https://jsfiddle.net/1oj3h417/2/

    Let me know if you have any doubt

    0 讨论(0)
  • 2020-12-17 10:33

    The setState function is executed in asynchronous context.

    By the time the state is updated the e.target reference might or might not be gone.

    const file = e.target.files[0]; can be used to "remember" the value as in your example.

    0 讨论(0)
提交回复
热议问题