V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
charlesliu
V2EX  ›  React

React 有什么比较优雅的跨组件通信方法吗

  •  
  •   charlesliu · 2022-02-16 21:25:27 +08:00 · 5462 次点击
    这是一个创建于 1016 天前的主题,其中的信息可能已经有所发展或是发生改变。
    在 A 组件上推送了某个消息,可以让不同级的组件 B 监听,并执行相应的任务。

    我首先想到了使用 Context ,保存一个变量,A 改变这个变量,B 使用 useEffect 监听变化。

    或者是使用 hox.js

    或者是使用 浏览器的 CustomEvent 。

    上述感觉都不够优雅
    37 条回复    2022-02-17 21:01:00 +08:00
    WildCat
        1
    WildCat  
       2022-02-16 21:42:33 +08:00
    Redux?
    tatu
        2
    tatu  
       2022-02-16 21:43:34 +08:00
    rxjs?
    seki
        3
    seki  
       2022-02-16 21:43:56 +08:00   ❤️ 1
    思路很多,比如
    + 加一个 event emitter
    + 加入 store
    + rxjs

    就看你为什么会觉得不优雅了
    ddiu8081
        4
    ddiu8081  
       2022-02-16 22:17:55 +08:00 via iPhone
    Recoil? A 组件 set ,B 组件 useValve
    rrfeng
        5
    rrfeng  
       2022-02-16 22:21:23 +08:00 via Android   ❤️ 5
    这时候 angular 的方便就体现出来了!可以直接通过 service 发布 /订阅 事件,跨多远都没关系。
    hanai
        6
    hanai  
       2022-02-16 22:42:18 +08:00
    event bus
    postMessage
    Rocketer
        7
    Rocketer  
       2022-02-16 23:00:00 +08:00 via iPhone
    angular 是用 rxjs 实现的,你也可以在 react 里使用 rxjs 。只是 angular 全面使用 rxjs 而 react 会有很多 promise ,混着写算不算另一种不优雅?
    theohateonion
        8
    theohateonion  
       2022-02-16 23:04:30 +08:00
    为什么不够优雅呢?你觉得优雅的方式是什么呢? Context + useEffect 就是一个简单的 pubsub ,不过缺乏统一的地方去管理这些订阅,可能是个问题。
    solos
        9
    solos  
       2022-02-16 23:04:42 +08:00
    @rrfeng angular 真香
    Leviathann
        10
    Leviathann  
       2022-02-16 23:07:15 +08:00
    react 比较推崇单向数据流 单一信源
    所以就弄个 store
    sweetcola
        11
    sweetcola  
       2022-02-17 00:10:16 +08:00
    可能你是觉得都用到了 Context (要写 Provider )不够优雅吗?

    看看 https://www.npmjs.com/package/react-signal-slot 这个符不符合你的想法,就是个不用写 Provider 的 event bus
    dayeye2006199
        12
    dayeye2006199  
       2022-02-17 07:01:46 +08:00
    context 不用引入额外依赖,多好
    xsen
        13
    xsen  
       2022-02-17 07:06:44 +08:00
    封装个 event bus ,这样不管是 react 组件、还是纯 js/ts 模块,都可以双向通讯
    跨 ui 框架了,还可以服用
    fliu2476
        14
    fliu2476  
       2022-02-17 08:59:49 +08:00
    zustand 香的不行
    fancy2020
        15
    fancy2020  
       2022-02-17 09:16:14 +08:00
    redux?
    gouflv
        16
    gouflv  
       2022-02-17 09:17:27 +08:00 via iPhone
    提问前,请先自己定义好什么样叫优雅
    boxz
        17
    boxz  
       2022-02-17 09:23:40 +08:00
    jotai
    Latin
        18
    Latin  
       2022-02-17 09:28:16 +08:00
    useContext or Redux
    karott7
        19
    karott7  
       2022-02-17 09:59:33 +08:00
    Redux 就好了
    ChefIsAwesome
        20
    ChefIsAwesome  
       2022-02-17 10:01:18 +08:00
    有一种“优雅”是必须用一个技术栈内的方案解决问题。
    另外一种“优雅”是融会贯通,跳出当前技术栈,从更广的范围内,找到最简单的方案解决问题。
    明显你这就是个常规小问题,怎么解决还不是看你心情。
    Hanggi
        21
    Hanggi  
       2022-02-17 10:11:34 +08:00
    有人提到 Angular , 确实在有大量数据操作的场景里,Angular 很简单很方便。

    跨组件状态共享,最传统的方法就是引入 Redux ,但是需要一点学习成本,且代码量会变多不少。好处就 i 是熟悉了之后可以进行统一的状态管理。

    个人比较推荐 Recoil ,使用起来非常简单高效,而且性能也很好。
    CodingNaux
        22
    CodingNaux  
       2022-02-17 10:13:53 +08:00
    既然是消息,那就使用订阅发布吧,custom event 之类可以呀,如果是一个简单的页面,怎么简单怎么来
    不是什么数据都要放 redux ,也不是什么情况都需要 redux
    rxjs 有点成本
    einq7
        23
    einq7  
       2022-02-17 10:14:05 +08:00
    useContext 结合 useReducer
    nanxiaobei
        24
    nanxiaobei  
       2022-02-17 10:52:33 +08:00
    charlesliu
        25
    charlesliu  
    OP
       2022-02-17 11:00:35 +08:00
    这确实是一个很小的 case ,不过也是因为小,就没有什么比较统一的方案,就感觉自己的实现方法不够简洁、通用,所以才来 v 站上咨询一下,开阔视野。

    如果是我个人的话,我也倾向于使用 rxjs ,不过在公司项目中这样使用,不见得引入它是个好的选择。

    感谢各位回答
    charlie21
        26
    charlie21  
       2022-02-17 11:22:51 +08:00
    useEffect 官网示例 开销最小做法
    https://zh-hans.reactjs.org/docs/hooks-effect.html

    关于何为优雅
    https://www.zhihu.com/question/47161776/answer/111488644#人们怎么编程: 先为对应的问题建立一个模型, 然后用代码设计出一套 DSL, 再将代码进行运算以解决问题。也就是 越符合你自己在脑海之中建立的模型,你就会觉得越优雅。这是你一个人的事,而这往往和你自己对问题的定义有关,而和问题的实际规模无关。相比优雅,对别人以优雅之名给杀鸡人推荐杀牛刀的警惕是更必要的
    AyaseEri
        27
    AyaseEri  
       2022-02-17 14:10:31 +08:00
    dispatchEvent
    addEventListener
    Incrus
        28
    Incrus  
       2022-02-17 15:43:44 +08:00 via iPhone
    Mobx
    star7th
        29
    star7th  
       2022-02-17 17:24:49 +08:00
    强烈推荐 Mobx https://cn.mobx.js.org/
    freedomT
        30
    freedomT  
       2022-02-17 17:48:42 +08:00   ❤️ 1
    mitt
    a935855375
        31
    a935855375  
       2022-02-17 18:41:31 +08:00
    Angular 通过 EventEmitter 。 可以搞个类似的 EventBus 服务
    linl1n
        32
    linl1n  
       2022-02-17 18:47:08 +08:00 via iPhone
    安利 Mobx
    code4you
        33
    code4you  
       2022-02-17 19:03:40 +08:00
    Mobx +1
    flashback313
        34
    flashback313  
       2022-02-17 19:32:23 +08:00
    Context 其实就是你要的答案,其他都是 pubsub 类
    2218675712
        35
    2218675712  
       2022-02-17 20:00:35 +08:00 via Android
    concent.js
    mxT52CRuqR6o5
        36
    mxT52CRuqR6o5  
       2022-02-17 20:57:50 +08:00
    如果是希望减少外部依赖的话,那就 context 或者 props 硬传
    Cbdy
        37
    Cbdy  
       2022-02-17 21:01:00 +08:00
    document.dispatchEvent
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1201 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 18:38 · PVG 02:38 · LAX 10:38 · JFK 13:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.