簡體   English   中英

input 的 event.target 在 this.setState [React.js] 中為 null

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

在我的反應組件中,我有一個文件輸入:

<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]; 可用於“記住”您的示例中的值。

使用 callback 調用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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM