記一次React中異步獲取事件對象的爬坑經歷

SyntheticEvent objects are pooled

在使用React過程當中,直接異步獲取事件對象上的屬性,實際上咱們拿到的值永遠是null,下面的代碼就存在問題緩存

const handleClick = e => {
        setTimeout(() => {
            console.log(e.target.name)
        });
    }

控制檯會輸出 null。出現上面這種狀況,React官方給出的解釋以下:異步

The SyntheticEvent is pooled. This means that the SyntheticEvent object will be reused and all properties will be nullified after the event callback has been invoked. This is for performance reasons. As such, you cannot access the event in an asynchronous way.async

在 React 事件處理中,事件對象被包裝在一個 SyntheticEvent(合成事件)對象中。這些對象是被池化的(pooled),這意味着在事件處理程序會把這些對象重用於其餘事件以提升性能。隨之而來的問題就是,異步訪問事件對象的屬性是不可能的,由於事件的屬性因爲重用而被重置(nullified)。性能

解決方式是把事件對象e 賦值到一個內部變量上。this

const handleClick = e => {
    let name = e.target.name;    //   將須要從事件對象上獲取的信息,先緩存到變量上面
        setTimeout(() => {
            console.log(name);
        });
    }

React 官方實例code

function onClick(event) {
  console.log(event); // => nullified object.
  console.log(event.type); // => "click"
  const eventType = event.type; // => "click"

  setTimeout(function() {
    console.log(event.type); // => null
    console.log(eventType); // => "click"
  }, 0);

  // Won't work. this.state.clickEvent will only contain null values.
  this.setState({clickEvent: event});

  // You can still export event properties.
  this.setState({eventType: event.type});
}

想異步訪問事件屬性,能夠在事件上調用event.persist(),這會從池中移除合成事件並容許對事件的引用被保留。orm

相關文章
相關標籤/搜索