当前位置: 首页 > 知识库问答 >
问题:

javascript - 不想组件之间通信想要通过状态组件实现,比如:zustand, mobx 这样的状态库, 想要使用事件监听库,请问是否有推荐呢?

云昊阳
2024-07-08

有一个需求,就是在React 页面中,比如有2个子组件,A和B,我想要通过一个三方库实现,B组件监听一个事件,A组件触发发送事件消息。
①不想要通过React默认的组件间通信实现
②也不想通过状态组件实现,比如:zustand, mobx 这样的状态库,
想要使用事件监听库,请问是否有推荐呢?

请问

2f22cc1b82e6ebf67fc5b0fb4bf81278.png

共有3个答案

史鸿运
2024-07-08

可以用使用pubsub-js,

小牛23179
2024-07-08

使用 CustomEvent

父组件:

const eventName = `event-${Math.random()}`

return <div>
    <CompA eventName={eventName} />
    <CompB eventName={eventName} />
</div>

组件 A:

dispatchEvent(new CustomEvent(eventName))

组件 B:

addEventListener(eventName, (e) => console.log(e))
龙俊美
2024-07-08

在React中,如果你想要在不使用默认的props和context进行组件间通信,也不使用像Zustand、MobX这样的状态管理库的情况下,实现事件监听和触发,你可以考虑使用自定义的事件系统或第三方的事件库。

不过,请注意,React的哲学通常鼓励使用其内置的props和context作为主要的通信手段,因为它们与React的渲染和更新机制紧密集成。然而,对于某些特殊用例或第三方集成,你可能确实需要一种更灵活的事件机制。

以下是一些你可以考虑的方案:

1. 使用事件发射器(Event Emitter)模式

你可以自己实现一个简单的事件发射器,或者使用像mitteventemitter3这样的第三方库。这些库通常提供了一个中央事件总线,你可以在其中注册监听器,并从任何地方触发事件。

使用mitt的示例:

首先,安装mitt

npm install mitt

然后,在你的React应用中使用它:

import mitt from 'mitt';

// 创建一个事件发射器实例
const emitter = mitt();

// 在组件A中触发事件
function ComponentA() {
  const handleClick = () => {
    emitter.emit('myEvent', 'some data');
  };

  return <button onClick={handleClick}>Trigger Event</button>;
}

// 在组件B中监听事件
function ComponentB() {
  useEffect(() => {
    function onMyEvent(data) {
      console.log('Received data:', data);
    }

    // 监听事件
    emitter.on('myEvent', onMyEvent);

    // 清理函数,确保在组件卸载时移除监听器
    return () => {
      emitter.off('myEvent', onMyEvent);
    };
  }, []);

  return <div>Listening for events...</div>;
}

2. 使用Redux或Redux Toolkit的actions和reducers

虽然Redux通常被视为一个状态管理库,但你也可以只使用它的actions和reducers作为事件系统。不过,请注意,这将引入Redux的整个架构和相关的复杂性,这可能并不是你想要的。

3. 使用React的自定义Hooks

你可以创建自定义的React Hooks来封装事件监听和触发的逻辑。这可以为你提供一种更声明式和可组合的方式来处理事件。然而,这仍然依赖于React的组件和渲染机制。

4. 使用全局变量或localStorage/sessionStorage

虽然这些方法通常不推荐用于组件间通信(因为它们可能导致难以追踪的副作用和状态管理问题),但在某些特殊情况下,它们可能是一个可行的选择。但是,请务必谨慎使用,并确保你完全理解它们的潜在问题。

总结

在选择任何方案之前,请确保你了解其优缺点,并考虑它是否适合你的具体用例和需求。在大多数情况下,使用React的内置通信机制(如props和context)可能是最简单、最可靠的选择。

 类似资料:
  • 本文向大家介绍iOS CoreTelephony 实现监听通话状态,包括了iOS CoreTelephony 实现监听通话状态的使用技巧和注意事项,需要的朋友参考一下 在程序中如果需要监听电话状态,可以引入CoreTelephony框架,这个框架包含了电话相关的API,可以实现监测来电,查看运营商信息等功能。下面就是具体的实现监测来电的代码。一定要把center写成一个单独的属性,并且是强引用(s

  • 请问一下有什么思路这样做到? 比如: 我有一个组件A(内有状态), 然后在我的一个容器面板中,我想要自由增加/删除组件A(也就是可以有多个组件A) 这里我有一点疑惑,每个组件都有名称一样的状态,我怎么做区分呢?特别是如果要结合zustand去保存状态,那么这里就重复了状态名。

  • let data=[ {id:1,width:500,height:1000}, {id:2,width:500,height:1000}, {id:3,width:500,height:500}, {id:4,width:500,height:500}, {id:5,width:500,height:1000}, {id:6,width:500,height:1000}, {id:7,width

  • 问题内容: 在我的一个类中,一种方法执行AJAX请求。在请求的回调函数中,我需要使用调用对象的另一个方法。但是在这种情况下并没有引用我的对象,所以我不知道该怎么做。 为了澄清,请考虑以下代码: 问题答案: 您可以定义一个变量存储在闭包中: 或使用$ .proxy: 或者,如果您不做任何事情,只需要调用回调: 在现代浏览器中,您也可以使用bind。当我不必与IE8兼容时,我可以

  • 问题内容: 我对Redis真的很感兴趣,我有一个主意,想知道它是否合适,或者是否对数据存储没有其他建议。同样,关于存储数据的任何技巧将不胜感激。 我的想法只是一个简单的事件系统,因此发生了一个事件,并将其存储在redis中,如下所示 关键 值[unixtimestamp]:[系统]:[事件] | [结果] 数据可以是任何销售,印象数,错误,api响应时间,页面加载时间以及任何实时分析数据。然后,我

  • 我需要使用父组件中子组件内部的状态值。 组成部分: 这是父组件: