React中events的踩坑指南
创始人
2024-06-03 21:06:13
0

本文介绍react项目中如何创建events来进行跨组件事件触发
重点讲解自定义参数传递,和如何拿到最新的state值🌟

创建和触发 events

// 创建event
const addEvent = (type, listener) => {window.addEventListener(type, listener);
};// 清除event
const removeEvent = (type, listener) => {window.removeEventListener(type, listener);
};// 触发event
const dispatch = (type, value?) => {// 触发事件,不传递数据// const event = new Event(type);// 触发事件,并可以传递参数const customEvent = new CustomEvent(type, { detail: value });window.dispatchEvent(customEvent);
};

注意⚠️
● 事件type不区分大小写,就是绑定’click’事件,派发’CLICK’或者’Click’,都会引起listener的执行
● new Event(type),触发事件,不能传递额外参数
● new CustomEvent(type),触发事件,可以传递额外value,我们这里把value放在了e.detail属性上,属性名可以自定义

🪤如何传递参数

点击按钮,打印出传递的参数

// 事件名称是不区分大小写
const EventName = 'myClick';function MyEvent() {// 2 点击按钮,触发事件const handleClick = () => {dispatch(EventName, { name: 'Jack', age: '18' });};// 1/3 执行回调函数const showData = (e) => {// 测试传递数据const data = e?.detail;console.log('传递的参数是', data);};// 1 绑定发布订阅关系useEffect(() => {addEvent(EventName, showData);return () => {removeEvent(EventName, showData);};}, []);return (
测试发布订阅模式加参数:
); } export default MyEvent;

🪤坑2 如何获取上下文state

逻辑:点击触发事件:打印上下文中的变量v1 和 state值

但是第一次点击按钮结果:
v1 is 变量1
state is
第二次点击按钮结果:
v1 is 变量2
state is
问题:拿不到最新的state值!!!

// 事件名称是不区分大小写
const EventName = 'myClick';function MyEvent() {const [state, setState] = useState('');let v1 = '变量1';const handleClick = () => {dispatch(EventName);};const showData = useCallback(() => {// 测试能否获取上下文console.log('v1 is ', v1);console.log('state is ', state); setState('11111');v1 = '变量2';}, [state]);
useEffect(() => {addEvent(EventName, showData);return () => {removeEvent(EventName, showData);};}, []);return (
测试发布订阅模式加参数:
); }export default MyEvent;

但是showData中为什么拿不到最新的state值呢?更准确的说,是回调函数showData中拿不到最新的值。
● 检查一下代码第27行,绑定回调函数是在页面第一次渲染时,
● 之后虽然state变化,但是之前绑定的回调函数不会变化
● 触发事件时,执行的还是页面第一次渲染时绑定的showData,里面的state还是页面第一次渲染时的state
正确代码

// 事件名称是不区分大小写
const EventName = 'myClick';function MyEvent() {const [state, setState] = useState('');let v1 = '变量1';const showData = useCallback(() => {// 测试能否获取上下文console.log('v1 is ', v1);console.log('state is ', state);setState('11111');v1 = '变量2';}, [state]);const handleClick = () => {dispatch(EventName);};useEffect(() => {addEvent(EventName, showData);return () => {removeEvent(EventName, showData);};}, [showData]); return (
测试发布订阅模式加参数:





{state}
); }export default MyEvent;

关于以上代码,可能又同学要问:
● 是state变化引起的showData的变化,那么27行useEffect的依赖项写state可以吗?
可以,但不建议。如果showData函数依赖很多state,每次都一个一个写,容易遗漏,也不直观
● useEffect的依赖项是个函数,导致重复渲染怎么办
useEffect对于依赖项是直接对值进行的比较。也就是意味着函数对比的话,就是地址进行比较,显然,每次创建的函数地址都是不同的。不仅仅是state变化,每一次值的改变,都会导致函数改变,所以需要给showData加缓存,如第8行,用useCallback包了一层

相关内容

热门资讯

365夜故事好词? 365夜故事好词?好词:动如脱兔 待兔守株 得兔忘蹄 东兔西乌 龟毛兔角 狐死兔泣 获兔烹狗 狐兔之...
魏忠贤是好人还是坏人? 魏忠贤是好人还是坏人? 魏忠贤是坏人。在我们的印象中,魏忠贤就是一个十恶不赦,谄媚逢迎,艰险阴狠的小...
柯南最新的一集对应的是漫画第几... 柯南最新的一集对应的是漫画第几话2,6,78话841-843香甜冰冷的快递香甜冰冷的快递对应漫画:F...
闽浙两地开展跨界流域突发环境事... 转自:中国环境网7月10日,福建省南平市生态环境局、浙江省丽水市生态环境局共同开展跨省应急联动演练。...
专访丨巴西看穿美国政治讹诈本质... 新华社里约热内卢7月11日电 题:巴西看穿美国政治讹诈本质 因而坚定“说不”——巴西法学教授卡瓦略谈...
拳脚生风展英姿!“英派斯杯”青... 7月10日-12日,“英派斯杯”青岛市第六届运动会青少年组跆拳道比赛在青岛市即墨区岘山小学举行。本次...
血液病学专家周淑芸逝世,享年9... 转自:京报网_北京日报官方网站 【#血液病学专家周淑芸逝...
守望:红色保密往事丨隐秘而伟大 转自:央视新闻客户端  百余年前中国,风雨飘摇。有一群人改名换姓,隐藏行踪,秘密集结,以独创暗语交换...
湖南汨罗一少年在游泳馆内触电身... 近日,有市民反映,湖南岳阳汨罗市一游泳馆内疑似发生因漏电致人死亡的事故。7月12日下午,澎湃新闻从汨...
中国煤炭大市:从“黑”到“绿”... 中新网鄂尔多斯7月12日电 题:中国煤炭大市:从“黑”到“绿”蜕变记中新网记者 李爱平“以前干活,摘...