input's event.target 在 this.setState [React.js] 中为 null



在我的react组件中我有一个文件输入:

<input type="file" onChange={this.onFileChange.bind(this)} />` 

我的onFileChange是:

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

这种设置状态失败的第一种错误:

Cannot read property 'files' of null

React还会发出以下警告:

This synthetic event is reused for performance reasons. If you're 
seeing this, you're accessing the property 'target' on a 
released/nullified synthetic event

但是,设定状态的最后两种方法没有给出任何错误或警告。为什么会发生这种情况?

setState函数在异步上下文中执行。

在状态更新时,e.target参考可能会或可能不会消失。

const file = e.target.files[0];可以用来"记住"示例中的值。

用回调调用setState的原因是什么?this.setState({ file: e.target.files[0] })应该做这项工作。

在您的代码中,您指的是一个不再包含有关原始DOM事件的信息的合成事件对象。出于性能原因,React将事件对象重用。

或者您可以使用:

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

react使用事件池,您可以在此处的文档中阅读有关它的更多信息https://reactjs.org/docs/events.html

setState是一个异步函数

this.setState(() => ({ file })); // is correct

非常简单/基本示例执行相同的任务:

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')
);

我添加了台式日志,即设置状态时,它将记录文件详细信息。选择文件时,您可以在日志中查看状态包含文件数据。

要查看需要右键单击并查看控制台的控制台日志。

结帐工作示例此处https://jsfiddle.net/1oj3h417/2/

让我知道您是否有疑问

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>

最新更新