javascript - reactjs中的事件监听器和闭包
问题描述
尽管添加了removeEvent ,但customFunction的控制台日志在每次渲染时都会打印多次。我知道这与关闭有关,但无法确定解决方案。任何帮助表示赞赏。
import React, { useEffect, useState } from "react";
function addOnEvent(event_name, callback){
document.addEventListener(event_name, (e)=>callback(e.detail));
}
function removeEvent(event_name, callback){
document.removeEventListener(event_name, callback);
}
function App() {
const [some_state, set_some_state] = useState([]);
const customFunction = (e) => {
//some action here setting some_state
console.log("Console prints multiple times")
};
useEffect(() => {
addOnEvent('custom_event', customFunction)
return () => {
removeEvent('custom_event', customFunction)
};
}, [some_state]);
return (
<div className="App">
</div>
);
}
export default App;
解决方案
您没有正确清理事件侦听器。这是因为您使用新的箭头函数包装了给定的回调。因此,removeEventListener
将找不到要删除的事件侦听器。
e.detail
您可以通过删除箭头功能并在您的中提取来解决此问题customFunction
。
import React, { useEffect, useState } from "react";
function addOnEvent(event_name, callback){
document.addEventListener(event_name, callback);
}
function removeEvent(event_name, callback){
document.removeEventListener(event_name, callback);
}
function App() {
const [some_state, set_some_state] = useState([]);
const customFunction = (e) => {
//some action here setting some_state
console.log("Console prints multiple times")
};
useEffect(() => {
addOnEvent('custom_event', customFunction)
return () => {
removeEvent('custom_event', customFunction)
};
}, [some_state]);
return (
<div className="App">
</div>
);
}
export default App;
如果您真的只想要e.detail
回调中的 ,您还可以更新该addOnEvent
函数以返回一个未侦听的函数,如下所示:
import React, { useEffect, useState } from 'react';
function addOnEvent(event_name, callback) {
const listener = e => callback(e.detail);
document.addEventListener(event_name, listener);
return () => document.removeEventListener(event_name, listener);
}
function App() {
const [some_state, set_some_state] = useState([]);
const customFunction = (e) => {
//some action here setting some_state
console.log('Console prints multiple times');
};
useEffect(() => {
const unlisten = addOnEvent('custom_event', customFunction);
return () => unlisten();
}, [some_state]);
return (
<div className="App">
</div>
);
}
export default App;
推荐阅读
- css - 如何将表单字段与文本内联?
- c# - 如果在加载时更改内容,则 StackPanel 中的 WPF 标签不会调整大小
- node.js - 从 readline 的线路回调中进行异步调用?
- embedded-linux - dbus-daemon --session 给出循环包含错误
- php - 根据下拉选择使用 PHP/MySQL 更改数据库
- docker - kafka消费者无法连接
- php - 在一定数量的列之后拆分html表
- java - 端点返回对象而不是直接 JSON
- java - 使用 Java 8 流查找数组中对角线元素的总和
- node.js - Sequelize where option sql injection?