[英]Using setTimeout inside React event, this synthetic event is reused for performance reasons
我寫了一個類似下面代碼的 React 組件
const RippleEffect = ({ children, controls }: any) => {
const ctrl = (controls || ['button']) as string[];
const effect = 'ripple';
const newChildren = React.Children.map(children, element => {
const onMouseDown = (e: any) => {
// e.persist(); Does not work!
const x = e.pageX - e.target.offsetLeft;
const y = e.pageY - e.target.offsetTop;
const w = e.target.offsetWidth.toString();
const ripple = document.createElement('span');
ripple.className = 'ripple';
ripple.style.left = x + 'px';
ripple.style.top = y + 'px';
ripple.style.setProperty('--scale', w);
e.target.appendChild(ripple);
// Necessary but problematic!
setTimeout(() => {
e.target?.parentNode?.removeChild(ripple);
}, 500);
};
if (ctrl.indexOf(element.type) != -1) {
return React.cloneElement(element, { effect, onMouseDown })
}
else {
return React.cloneElement(element)
}
});
return newChildren;
}
可以這樣使用代碼
<RippleEffect>
<button type="button" className="btn btn-primary">Primary</button>
<button type="button" className="btn btn-secondary">Secondary</button>
<button type="button" className="btn btn-success">Success</button>
</RippleEffect>
看起來一切正常,但我在瀏覽器控制台中收到此錯誤:
Warning: 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. This is set to null. If you must keep the original synthetic event around, use event.persist().
我認為當我在onmousedown
事件中使用setTimeout
時會出現問題。 我在 onMouseDown function 的第一行使用了onMouseDown
e.persist()
但它破壞了整個過程!
NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
誰能幫我解決這個問題並刪除警告?
我解決了這個問題
setTimeout(() => {
ripple.remove();
}, 500);
代替
setTimeout(() => {
e.target?.parentNode?.removeChild(ripple);
}, 500);
您對e.persist()
的想法是正確的,當您調用 function 時,React 會從池中刪除合成事件,這允許異步使用對它的引用,這就是您通過調用setTimeout
本質上所做的事情。 你應該堅持這個事件。 您收到NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
錯誤是您將漣漪附加到event.target
,這是按鈕。 但是您在按鈕父節點上調用removeChild
。
取消注釋e.persist()
並更改e.target?.parentNode?.removeChild(ripple);
到e.target?.removeChild(ripple);
.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.