学习 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 1
至于你说为什么还要多此一举用 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 1
放在以前,没有 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
看情况使用,这其实是一个单例和多例的问题。
|