登录
首页 >  文章 >  前端

为何React组件间通信的mitt事件监听器会重复触发?

时间:2025-03-28 10:09:34 437浏览 收藏

React组件间通信使用mitt库时,组件B的事件监听器可能重复触发,导致数据打印多次。这是因为组件B的useEffect钩子在每次重新渲染时都会重新添加事件监听器。本文分析了基于mitt库的React组件A和组件B通信案例,指出问题根源在于useEffect中缺少监听器移除逻辑。解决方案是在useEffect中使用`emitter.on`返回的`unsubscribe`函数,在组件卸载时移除监听器,确保事件监听器只添加一次,从而避免重复触发。 文章详细讲解了问题代码、问题根源及改进后的代码,并强调了在useEffect的返回值中清理监听器的重要性。

React组件间通信:mitt事件监听器为何重复触发?

React组件间通信:使用mitt库时避免事件监听器重复触发

本文分析一个使用mitt库在React组件间通信的案例,解释为何点击组件A的按钮后,组件B的事件监听器会重复触发的问题,并提供解决方案。

代码示例包含两个React组件:组件A和组件B,它们通过名为emitter的mitt实例进行通信。组件A包含一个按钮,点击该按钮会发出名为e1的事件,并携带数据。组件B监听e1事件,并在事件触发时打印接收到的数据。

问题代码:

组件A:

import { useEffect } from 'react';
import emitter from '../../emitter';

function Index() {
    useEffect(() => {
        console.log('组件A挂载');
    }, []);

    return (
        
    );
}

export default Index;

组件B:

import { useEffect } from 'react';
import emitter from '../../emitter';

function Index() {
    useEffect(() => {
        console.log('组件B挂载');
        emitter.on('e1', (e) => {
            console.log('mitt test', e);
        });
    }, []);

    return 
BBB
; } export default Index;

emitter/index.ts:

import type { Emitter } from 'mitt';
import mitt from 'mitt';

export default mitt() as Emitter;

问题根源:

组件B的useEffect钩子中的emitter.on('e1', ...)语句在每次组件B重新渲染时都会执行,导致e1事件的监听器被重复添加。每次重新渲染(例如,由于状态变化),useEffect都会重新运行,从而再次添加事件监听器。因此,当组件A发出e1事件时,组件B中的监听器会被多次执行。

解决方案:

为了确保emitter.on('e1', ...)只执行一次,需要在useEffect中添加清除监听器的逻辑,并在组件卸载时移除监听器:

改进后的组件B:

import { useEffect } from 'react';
import emitter from '../../emitter';

function Index() {
    useEffect(() => {
        const unsubscribe = emitter.on('e1', (e) => {
            console.log('mitt test', e);
        });
        return () => unsubscribe(); // 组件卸载时移除监听器
    }, []);

    return 
BBB
; } export default Index;

return () => unsubscribe();这行代码会在组件卸载前执行,移除之前添加的事件监听器,从而避免重复触发。这确保了事件监听器只添加一次,解决了重复打印的问题。

通过以上修改,可以有效解决mitt事件监听器在React组件间通信中重复触发的难题。 记住在useEffect的返回值中使用unsubscribe函数来清理监听器至关重要。

本篇关于《为何React组件间通信的mitt事件监听器会重复触发?》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于文章的相关知识,请关注golang学习网公众号!

相关阅读
更多>
最新阅读
更多>
课程推荐
更多>