React / Mobx 全局状态管理问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
taofoo
V2EX    React

React / Mobx 全局状态管理问题

  •  
  •   taofoo 2022-05-09 11:30:26 +08:00 3566 次点击
    这是一个创建于 1277 天前的主题,其中的信息可能已经有所发展或是发生改变。

    学习 React 看到了这个帖子 https://zhuanlan.zhihu.com/p/114292057

    大概说的内容是用 mobx 创建了一个 TodoStore 实现了全局的状态管理。 问题在这里,既然用了 mobx 为何还要用 Provider?不是很明白。通过 observer 不是已经可以监听 store 的变化了吗?

    下面是代码贴的是上面帖子里面的

    // ./src/app.tsx import React from 'react'; import { Provider } from 'mobx-react'; import Routers from './containers/routers'; import { stores, StoresContext } from './stores'; function App() { return ( // 服务类组件 <Provider {...stores}> {/* 服务函数组件 */} <StoresContext.Provider value={stores}> <Routers /> </StoresContext.Provider> </Provider> ); } export default App; 
    // ./src/containers/todo-list-fn/index.tsx import React from 'react'; import { observer } from 'mobx-react'; import { useTodoStore } from '../../stores'; function TodoListFnPage() { const { todos, undoneCount, doneCount, addNewTodo, removeById, toggleStatusById } = useTodoStore(); // 注意这里的 observer export default observer(TodoListFnPage); 
    22 条回复    2022-05-09 22:22:35 +08:00
    CodingNaux
        1
    CodingNaux  
       2022-05-09 11:37:50 +08:00
    你看的资料有些过时,直接看官方文档吧,现在都是用 mobx-react-lite ,装饰器写法已经不推荐了
    https://mobx.js.org/react-integration.html
    statumer
        2
    statumer  
       2022-05-09 11:41:53 +08:00 via iPhone
    官方有文档为什么要看三流学习笔记
    CodingNaux
        3
    CodingNaux  
       2022-05-09 11:43:35 +08:00   1
    至于你说为什么还要多此一举用 Provider ,旧的文档这么写就这么用吧,深究需要看代码,一个 mobx 与 react 的 adapter 代码也不会太多
    cszchen
        4
    cszchen  
       2022-05-09 11:48:43 +08:00 via iPhone
    不明觉厉,我之前做一个简单的项目,用的 resso
    taofoo
        5
    taofoo  
    OP
       2022-05-09 11:53:45 +08:00
    @CodingNaux 好的,我自己没用 Context 那一套,直接用 mobx 是可以的。有待深究
    taofoo
        6
    taofoo  
    OP
       2022-05-09 11:54:17 +08:00
    @CodingNaux 嗯,瞅瞅去
    taofoo
        7
    taofoo  
    OP
       2022-05-09 11:59:39 +08:00
    @statumer 确实,不过我简略的过一遍 react 遇到全局状态问题,想找一个完整一点的例子。搜了一下看到了这个
    taofoo
        8
    taofoo  
    OP
       2022-05-09 12:00:47 +08:00
    @cszchen 之前看到过,挺小的
    statumer
        9
    statumer  
       2022-05-09 12:13:59 +08:00
    @taofoo mobx 是可以和 context 一起用的,很简单就可以实现按需更新,而不是重渲染所有 Context Consumer 组件( React Context 的默认行为)。官网就有示例。
    otakustay
        10
    otakustay  
       2022-05-09 12:24:18 +08:00   1
    放在以前,没有 Provider 大致也是行的,包括 redux 如果你是严格单 store ,其实也能直接拿 store 过来再 getState 玩,自己去 listen 就行
    总体上用 Provider 应该有 2 个考虑:
    1. 所有版本下,如果你要支持多个 store ,那就得用不同位置的 Provider 区分下面的子组件用哪个 store
    2. 在 React 18 以后的并发模式下,直接用 store 会状态撕裂,所以要用 useExternalSyncStore ,这东西还是挺复杂的,损耗也不少,所以最好在 Provider 集中处理再丢给下面
    taofoo
        11
    taofoo  
    OP
       2022-05-09 12:29:47 +08:00
    @statumer 那使用 observer 在 store 更新的时候会重新渲染所有引用 store 的组件的吗?
    taofoo
        12
    taofoo  
    OP
       2022-05-09 12:38:12 +08:00
    @otakustay 对于第二点没啥问题。对于第一点,Provider 是不是更像是一种规范?因为子组件也可以自己直接导入 store 。不知道这么理解对不对
    gogogo1203
        13
    gogogo1203  
       2022-05-09 13:11:06 +08:00
    如果想更方便可以改用 zustand
    otakustay
        14
    otakustay  
       2022-05-09 13:33:44 +08:00
    @taofoo #12 子组件自己导入就形成了耦合了,用 Provider 的话可以在 Provider 层面换一个结构一样的 store 。有一些比较极端的实现,比如一个列表 List 里,每个 ListItem 都套一个 Provider 提供当前的 item 数据,这种时候显然子组件考虑自己的通用性,不可能去直接导入 store
    taofoo
        15
    taofoo  
    OP
       2022-05-09 13:36:47 +08:00
    @otakustay 嗯,有点想通了,我在想想。多谢解答!
    taofoo
        16
    taofoo  
    OP
       2022-05-09 13:44:53 +08:00
    @gogogo1203 react 选择这么多样化的吗 ,哈哈
    L1shen
        17
    L1shen  
       2022-05-09 14:39:37 +08:00
    还可以用 valtio
    gogogo1203
        18
    gogogo1203  
       2022-05-09 15:31:47 +08:00
    gogogo1203
        19
    gogogo1203  
       2022-05-09 15:36:26 +08:00
    @taofoo 不管用什么 global state manager , 用 reducer pattern+ immer 应该都差不多. 怎么方便怎么来吧。 用 React-Query 来管来自服务器的数据,用 zustand 管 client side state.
    ljpCN
        20
    ljpCN  
       2022-05-09 16:01:08 +08:00
    个人理解。Provider 在于可以隔离。外部代码使用你编写的组件时,可以在多个地方使用,而他们的内部状态不能引用同一个 mobx 实例,使用 provider 可以保证每个组件内的 mobx 实例是来自它自己的顶层 provider 。两颗组件树访问不同的实例。
    ljpCN
        21
    ljpCN  
       2022-05-09 16:02:27 +08:00
    而如果是自己项目的全局独一份的 store ,我觉得的确没必要套一层 provider 。
    gesneriana
        22
    gesneriana  
       2022-05-09 22:22:35 +08:00
    看情况使用,这其实是一个单例和多例的问题。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5743 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 117ms UTC 01:51 PVG 09:51 LAX 17:51 JFK 20:51
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86