Skip to content

使用 react hooks 获取全局数据 #1

@dancerphil

Description

@dancerphil

使用 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 提供了 setload 方法,与组件的生命周期脱钩,可以在任何时刻调用,比如 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 teamseniverse前端团队 以及 otakustay 对于此项目的支持。

如果你有更多的问题,可以联系,或在 github 提 issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions