
学习 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); 1 CodingNaux 2022-05-09 11:37:50 +08:00 你看的资料有些过时,直接看官方文档吧,现在都是用 mobx-react-lite ,装饰器写法已经不推荐了 https://mobx.js.org/react-integration.html |
2 statumer 2022-05-09 11:41:53 +08:00 via iPhone 官方有文档为什么要看三流学习笔记 |
3 CodingNaux 2022-05-09 11:43:35 +08:00 至于你说为什么还要多此一举用 Provider ,旧的文档这么写就这么用吧,深究需要看代码,一个 mobx 与 react 的 adapter 代码也不会太多 |
4 cszchen 2022-05-09 11:48:43 +08:00 via iPhone 不明觉厉,我之前做一个简单的项目,用的 resso |
5 taofoo OP @CodingNaux 好的,我自己没用 Context 那一套,直接用 mobx 是可以的。有待深究 |
6 taofoo OP @CodingNaux 嗯,瞅瞅去 |
9 statumer 2022-05-09 12:13:59 +08:00 @taofoo mobx 是可以和 context 一起用的,很简单就可以实现按需更新,而不是重渲染所有 Context Consumer 组件( React Context 的默认行为)。官网就有示例。 |
10 otakustay 2022-05-09 12:24:18 +08:00 放在以前,没有 Provider 大致也是行的,包括 redux 如果你是严格单 store ,其实也能直接拿 store 过来再 getState 玩,自己去 listen 就行 总体上用 Provider 应该有 2 个考虑: 1. 所有版本下,如果你要支持多个 store ,那就得用不同位置的 Provider 区分下面的子组件用哪个 store 2. 在 React 18 以后的并发模式下,直接用 store 会状态撕裂,所以要用 useExternalSyncStore ,这东西还是挺复杂的,损耗也不少,所以最好在 Provider 集中处理再丢给下面 |
12 taofoo OP @otakustay 对于第二点没啥问题。对于第一点,Provider 是不是更像是一种规范?因为子组件也可以自己直接导入 store 。不知道这么理解对不对 |
13 gogogo1203 2022-05-09 13:11:06 +08:00 如果想更方便可以改用 zustand |
14 otakustay 2022-05-09 13:33:44 +08:00 @taofoo #12 子组件自己导入就形成了耦合了,用 Provider 的话可以在 Provider 层面换一个结构一样的 store 。有一些比较极端的实现,比如一个列表 List 里,每个 ListItem 都套一个 Provider 提供当前的 item 数据,这种时候显然子组件考虑自己的通用性,不可能去直接导入 store |
16 taofoo OP @gogogo1203 react 选择这么多样化的吗 ,哈哈 |
17 L1shen 2022-05-09 14:39:37 +08:00 还可以用 valtio |
18 gogogo1203 2022-05-09 15:31:47 +08:00 |
19 gogogo1203 2022-05-09 15:36:26 +08:00 @taofoo 不管用什么 global state manager , 用 reducer pattern+ immer 应该都差不多. 怎么方便怎么来吧。 用 React-Query 来管来自服务器的数据,用 zustand 管 client side state. |
20 ljpCN 2022-05-09 16:01:08 +08:00 个人理解。Provider 在于可以隔离。外部代码使用你编写的组件时,可以在多个地方使用,而他们的内部状态不能引用同一个 mobx 实例,使用 provider 可以保证每个组件内的 mobx 实例是来自它自己的顶层 provider 。两颗组件树访问不同的实例。 |
21 ljpCN 2022-05-09 16:02:27 +08:00 而如果是自己项目的全局独一份的 store ,我觉得的确没必要套一层 provider 。 |
22 gesneriana 2022-05-09 22:22:35 +08:00 看情况使用,这其实是一个单例和多例的问题。 |