它說:“每次我們的組件渲染時,我們的效果都會被呼叫,添加另一個事件偵聽器。只需點擊幾下并重新渲染,我們就將很多事件偵聽器附加到 DOM!我們需要在之后清理我們自己!”。
所以對于每次點擊,計數從 1 到 3 到 7,而不是增加 1。我不明白如何附加這么多事件偵聽器以及這如何影響總計數?
import React, { useState, useEffect } from 'react';
export default function Counter() {
const [clickCount, setClickCount] = useState(0);
const increment = () => {
setClickCount(prev => prev 1);
};
useEffect(() => {
document.addEventListener('mousedown', increment);
})
return (
<h1>Document Clicks: {clickCount}</h1>
);
}
uj5u.com熱心網友回復:
您正在向檔案本身添加一個偵聽器,因此在卸載組件時需要將其洗掉。
并且您需要添加一個空的依賴陣列,以免在每次重新渲染時添加新的偵聽器
您要么需要包裝increment在 a 中,要么在 中useCallback使用不同的增量函式useEffect:
import React, { useState, useEffect } from 'react';
export default function Counter() {
const [clickCount, setClickCount] = useState(0);
const increment = useCallback(() => {
setClickCount(prev => prev 1);
}, [setClickCount]);
useEffect(() => {
document.addEventListener('mousedown', increment);
return () => document.removeEventListener('mousedown', increment);
}, [])
return (
<h1>Document Clicks: {clickCount}</h1>
);
}
uj5u.com熱心網友回復:
如果不使用依賴項陣列,每次更改都會觸發您useEffect再次運行。
因此,每次重新渲染、每次更改狀態都會導致您創建另一個eventListener.
讓我們談談變體useEffect:
useEffect(() => {
// invoking on every re-render
})
useEffect(() => {
// invoking on component did mount (once)
}, [])
useEffect(() => {
// invoking on component did mount and with every change on counter
}, [counter])
此外,您需要洗掉eventLinstener組件卸載:
useEffect(() => {
document.addEventListener('mousedown', increment);
return () => document.removeEventListener('mousedown', increment);
}, [])
可選的
正如 Samathingamajig 在答案中提到的,您可以使用優化的方式來定義您的increment函式useCallback。
對于當前的實作,您的increment方法每次都會被重新定義(每次更改和重新渲染),但useCallback只有在useCallback依賴項的陣列發生更改時才會重新定義使用它。
import React, {useEffect, useCallback} from 'react';
// rest of the codes ...
const increment = useCallback(() => {
setClickCount(prevState => prevState 1);
}, [setClickCount]);
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/342380.html
標籤:javascript 反应
