-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] useGlobalState 全局状态 #1832
Comments
@brickspert 有什么意见不 |
关于全局状态管理,我们建议使用 hox,ahooks 里不建议加这个 Hooks |
感谢 RFC 哈! |
这个是用批量更新实现的全局状态,不是用的context |
实现是用全局的一个 globalStates 去管理,相当于脱离了 React 的范围之外了,这样好么? |
那我用 Context 去管理岂不是更好么,感觉不到优势在哪呢 |
可以实现组件卸载可以清除globalStates里面存的内容,优势在于不需要provider,useContext,createContext @hchlq |
我的意思不是 ”组件卸载可以清除里面存的内容“。如果是 React 18 之后的,该如何考虑,状态管理是不建议脱离 React 的范围的 而且 createContext 我也可以封装,使用也很方便呀 |
我以为你考虑的是内存泄漏的问题,你可以举例说明可能会有什么问题吗 @hchlq |
createContext 容易被滥用,开发者可能会往里面放很多东西,useGlobalState设计跟useState是一样的,可以防止这一点 |
没有特别好的举例,但是状态尽量不要脱离 React 的范围~ |
滥用是相对而言的,团队中通过一些开发原则就可以避免了 |
但是这样也没有脱离react范围,实际设置状态和读取状态都是react的useState |
但是你会间接额外的维护状态和更新函数呀,我觉得不是特别有必要,看下 @brickspert 怎么说~ |
你的 demo 看起来比较简单,怎么处理多个数据呢 比如有 Global-A、 Global-B、Global-C,看起来得这样..? const useGlobalA = () => useGlobalState('A');
const useGlobalB = () => useGlobalState('B');
const useGlobalC = () => useGlobalState('C');
const A = () => {
const [globalA] = useGlobalA();
const [globalB] = useGlobalB();
const [globalC] = useGlobalC();
return <div>组件A:{globalA}{globalB}{globalC}</div>;
}; |
@miracles1919 是的,它跟useState一样,只不过多了个key |
那感觉实用性不是很大啊... 真实的场景下往往是需要聚合多组数据的,个人觉得没有必要加在 ahooks 里 关于全局状态管理,我们推荐使用 hox |
多个数据组合也可以这样用,useState可以怎么用,它就可以怎么用 const useGlobalABC = () => {
const [globalA] = useGlobalState('A');
const [globalB] = useGlobalState('B');
const [globalC] = useGlobalState('C');
return { globalA, globalB, globalC };
};
const A = () => {
const {globalA, globalB, globalC} = useGlobalABC();
return <div>组件A:{globalA}{globalB}{globalC}</div>;
}; |
@miracles1919 组合使用的例子我加了,你看看 |
我有个小问题,如果在多个组件中都调用了 const Foo = () => {
const [counter, setCounter] = useGlobalState('counter', 1)
// ...
}
const Bar = () => {
const [counter, setCounter] = useGlobalState('counter', 2)
// ...
} |
key重复是不好避免的问题,但是像useLocalStorage这些都是用的key,大家普遍在用一般不会遇到什么问题。初始值只会在第一个使用到的地方才会生效,这个容易让用户困惑,但是可以加一些警告说初始值没有生效来避免 |
这么说的话... useLocalStorage 完全能代替啊 |
useLocalStorage不会更新所有用到的地方啊....你看看例子呢。而且有全局状态需求的地方并不一定有存储local storage的需求啊 |
我的结论是,这个 Hook 只适合简单的项目,稍微复杂的项目还是要引入正儿八经的状态库的。 |
很早期我就有在大大小小的项目使用了,目前没什么问题,甚至有很多好处。这个就是使用很简单,如果项目是需要靠使用门槛来限制全局状态的使用,用别的状态库也是可以的。 |
用 key 这个方案,设计上就是有缺陷的,例如 #1832 (comment) 写的 demo,没有办法解决重复 key 的问题 设计上的问题,需要人为的方式避免(比如警告?),肯定是不合理的,一旦项目规模或者团队规模起来了,就是在给他们埋坑 这个就在你的项目中自己维护吧 |
useLocalStorage难道大型项目里面不能用吗,用了useLocalStorage就是在埋坑吗 |
如果 useLocalStorage 用于全局状态,那确实是在埋坑... |
你的全局状态概念还是传统的里面乱七八糟放很多东西,这种情况全局状态不好管理,但这个全局状态就只是一个状态了,副作用没那么大。 比如一个暗色主题切换,主题色切换,第一直觉就会让人用这个工具,他们本身就是一个状态而已。 |
而且这样状态颗粒度低,性能也好优化,避免了传统全局状态里面放的东西太多,带来的不必要的渲染 |
1、我上面说的是这个 Hook 作为全局状态,设计上的弊端
结合起来就是 #1832 (comment) 这个例子,使用 Foo 组件的时候 Count 是 1,使用 Bar 组件的时候 Count 变成了 2,反而会增加复杂性 2、对于全局状态的数据规模,如果复杂度比较低,比如一个主题色切换,那使用传统的状态管理一样有这些优点 但是反过来,如果全局状态有一定的复杂度,用 所以,这个 RFC 个人觉得没有必要,先关了。有问题可以继续讨论哈 |
一般使用都是会二次封装比如例子useGlobalStep,因为没人想重复去写key和初始值还有类型,复杂例子我也写了的useGlobalABC,我个人觉得很多人被redux、dva给教化了,没有需求制造需求,简单的反而是异类了 |
我现在一直用 hox,很简单的一个状态管理库。 |
我认为这个 hook 还是挺有意思的,有点类似于 vue 中将 ref 变量放到 composition api 外。 改造了一下 demo ,可以参考。https://codesandbox.io/s/dumi-demo-forked-z6j9zh?file=/combination-use.tsx |
reactjs/rfcs#224 (comment) |
useGlobalState
React Hook 实现一个全局状态的功能,不同页面不同组件使用同一个状态。Preview →
QQ20220824-192401-HD.mp4
Usage
1.先为全局状态设置一个唯一
key
,或者还可以设置一个初始值或者二次封装一个
useGlobalStep
2.在其他组件或者页面引入
useGlobalState
并使用相同的key
或者使用二次封装的
useGlobalStep
API
useGlobalState<T>(key: string, initState?: T): [T, (state: T) => void]
string
key
any
Demo
The text was updated successfully, but these errors were encountered: