[英]Understanding click events and memory in react function components
我一直在使用函數組件和鈎子,現在我正在嘗試更深入地研究事件以及它們如何保存在內存中。 我一直在使用 chrome 開發工具性能選項卡來監控行為。 有幾件事我不清楚,也許有人可以為我澄清。
所以我做了3個不同的設置。 第一個顯示事件明顯內存泄漏的事件在每次渲染時添加了多次。 這最終會導致渲染崩潰或無限循環。 或者至少那是看起來正在發生的事情。
const App = () => {
const [count, setCount] = React.useState(0);
const onKeyDown = () => setCount(count => count + 1);
document.addEventListener('keydown', onKeyDown);
return (
<div className='wrapper'>
<div>Click any key to update counter</div>
<div className='counter'>{count}</div>
</div>
);
};
ReactDOM.render(<App />, document.querySelector("#app"))
這表明每個偵聽器的額外事件調用明顯增加。 查看事件日志,然后增加已添加的事件階梯。
接下來
const App = () => {
const [count, setCount] = React.useState(0);
const onKeyDown = () => setCount(count => count + 1);
React.useEffect(() => {
document.addEventListener('keydown', onKeyDown);
return () => document.removeEventListener('keydown', onKeyDown);
}, [] );
return (
<div className='wrapper'>
<div>Click any key to update counter</div>
<div className='counter'>{count}</div>
</div>
);
};
ReactDOM.render(<App />, document.querySelector("#app"))
結果更好,因為聽眾一次只有一個電話。 但我注意到聽眾人數仍在飆升。 添加它們時的峰值並不那么尖銳。 但是聽眾的人數是千人。 所有這些聽眾在哪里被添加。 jsfiddle 是否添加了偵聽器。 最好將這個測試隔離在 jsfiddle 之外的一個 html 頁面中。
然后我讀到了使用鈎子 useCallback 來記住函數並返回函數的兌現版本。 所以我嘗試了這個。
const App = () => {
const [count, setCount] = React.useState(0);
const cb = React.useCallback(() => {
console.log('cb');
setCount(count => count + 1);
}, [] );
return (
<div className='wrapper'>
<div onClick={cb}>Click any key to update counter</div>
<div className='counter'>{count}</div>
</div>
);
};
ReactDOM.render(<App />, document.querySelector("#app"))
但結果證明這與上次使用 useEffect 的測試類似。 仍然有大量的聽眾,但沒有像第一次測試那樣崩潰。
那么這里的交易是什么我錯過了使用 useCallback 鈎子進行記憶的一些東西。 偵聽器看起來像是被瘋狂添加而沒有被垃圾收集。
我將在沒有 jsfiddle 的情況下隔離此測試,但只是想發布到社區以首先對此有所了解。
你不要在 React 中使用 addEventListener !
相反,你會做這樣的事情:
const App = () => {
let count = 0;
const onAddHandler = () => {
count++;
console.log(count);
this._count.innerText = count;
}
return (
<div className='wrapper'>
<div onClick={()=>onAddHandler()}>Click any key to update counter</div>
<div className='counter' ref={(el) => this._count = el}></div>
</div>
);
}
另外,不確定您為什么使用 React.useState。 功能組件的全部意義在於它們是無狀態的。 我不喜歡在功能組件中使用這個新的 useState 鈎子。
您可能正在尋找使用鈎子的示例是:
import React, { useState, useEffect } from 'react';
import {render} from 'react-dom';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
render(<Example />, document.getElementById('root'));
React 文檔https://reactjs.org/docs/hooks-effect.html說
如果您熟悉 React 類的生命周期方法,您可以將 useEffect Hook 視為 componentDidMount、componentDidUpdate 和 componentWillUnmount 的組合。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.