-
Notifications
You must be signed in to change notification settings - Fork 0
Description
使用 react hooks 获取全局数据
随着 react@16.8 hooks 的正式发布,如何优雅的使用 hooks 成了值得我们考虑的问题,在此我不再赘述 hooks 给 react 的写法带来的改变,而是介绍一个新的 hook。
试想有这样一个 hook
const { user } = useProps('user');如果我们有这样一个 hook,可以在全局的 store 中得到变量,同时解决了 useState 不能在组件之间共享的问题,无疑是可以提升开发效率的。
而现在,useProps 已经拥有了实现:region-core
useProps 提供哪些功能
得到多个变量
从全局数据中挑出你想要的数据,就像 lodash.pick 一样。
const { user, follower } = useProps(['user', 'follower']);以下的用法是支持的,但是不推荐
const { user } = useProps('user');
const { follower } = useProps('follower');自动的 loading 和 error
就像组件生命周期一样,数据通过区分是否 loading 和是否 error,可以分成三个状态: loading, loaded, error,对应一个数据抓取过程的 pending, resolved, rejected。(其中 resolved 和 rejected 都是 loaded)这样的分类是在长期实践中诞生的。
与 redux 完全不处理异步不同,region-core 内部有非常完善的异步处理,可以处理多个数据的多个请求。
const { loading, error, user, follower } = useProps(['user', 'follower']);此时,如果 user 或者 follower 中的任何一个在 loading,loading 为 true,只有两个都是 loaded, loading 为 false。
如果你只关心某几个数据的 loading 状态
const { loading, error, user } = useProps('user');
const { follower } = useProps('follower');配合 useProps
通常在 redux,想把数据存入 store,需要经过 action, middleware 和 reducer。无论是哪一块都需要代码量,但是在 region-core 是没有 redux 的这些概念的。
region-core 提供了 set 和 load 方法,与组件的生命周期脱钩,可以在任何时刻调用,比如 componentDidMount 或者 onClick,甚至可以在组件定义之前就已经处理了数据。
const setUser = (user) => set('user', user);
const loadUser = () => load('user', fetchUser);
setUser('defaultUser');
const UserButton = () => <Button onClick={loadUser} />;
export default UserButton;变量的局部 namespace
至此,你已经可以使用 region-core 快速开发小型 App 了,但是你可能还有一些顾虑。
相对于 redux 复杂的结构,region-core 的内部结构是不暴露的,开发者所做的只是通过变量名得到变量,或者通过变量名控制变量,如果所有的变量都是全局的,那么 region-core就不能很好的支持大型项目。
但事实上它可以,通过一个 Region 类,开发者可以定制一个 namespace,这也是 region-core 的起名的来源。
const myRegion = new Region('myRegion');
const { set, load, useProps } = myRegion;不同的 region 实例,变量之间不会相互干扰,甚至你可以通过一些 option 来控制一个 region 中的数据行为,详细的 api 可以参考文档
const myRegion = new Region({
name: 'myRegion',
expiredTime: 60000,
...
});高可拓展性
一旦接受了 Region 的概念,在它提供的数据支持之上,可以开发出适用于业务的 Region 拓展
class MyRegion extends Region {
constructor(...args) {
super(...args);
this.someFunc = this.someFunc.bind(this); // in case you are not using class field
}
someFunc() {}
}其中,官方就提供了一个 region-form,可以对 antd 中的所有表单组件进行自动的数据双向绑定,如果没有一个 Region 的支持,这是做不到的。
支持 redux
如果你正在使用 redux 并使用 react-redux connect 数据到组件上,你不必放弃他们。
事实上,你只要升级到 redux@4 和 react-redux@6,你就可以使用 region-core 并得到你原来的所有代码的兼容。
如果你想开个新项目试试,你需要添加一个 Provider,而如果你正在使用 react-redux@6 中的 Provider,则是可以兼容的,虽然你可能要多写一行代码防止你的 reducers 被 Region 覆盖。
感谢
感谢 Baidu EFE team,seniverse前端团队 以及 otakustay 对于此项目的支持。