返回

Rematch 源码系列四:Third-Party plugins

前端

前言

Rematch 源码系列三 中,我们介绍了 Rematch 的插件机制以及其核心的两个插件:redux-thunkredux-persist。除了这两个插件外,Rematch 团队其实还开发了不少第三方插件,这些插件可以帮助我们更加轻松地使用 Rematch 来管理状态。

本文将介绍两个第三方插件:immerloading,以及如何使用它们来增强 Rematch 的功能。

Immer

Immer 是一个 JavaScript 库,它可以帮助我们以一种更安全、更简洁的方式来管理不可变数据。在 Redux 中,我们通常使用 Object.assign()_.assign() 来创建新的状态对象。然而,这些方法会创建新的对象,这可能会导致性能问题。Immer 提供了一种更好的方法来创建新的状态对象,它不会创建新的对象,而是直接修改现有的对象。

为了使用 Immer,我们需要先安装它:

npm install immer

然后,我们需要在 Rematch 的配置文件中启用它:

// rematch.config.js
const config = {
  plugins: [
    // ...其他插件
    require('immer')(),
  ],
};

module.exports = config;

启用 Immer 后,我们就可以在 Redux 的 reducer 中使用它了。例如,以下代码使用 Immer 来更新一个状态对象:

// reducer.js
export default (state = initialState, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return produce(state, draft => {
        draft.todos.push(action.payload);
      });

    default:
      return state;
  }
};

在上面的代码中,produce() 函数是 Immer 提供的,它可以帮助我们以一种安全、简洁的方式来更新状态对象。produce() 函数接受两个参数:第一个参数是需要更新的状态对象,第二个参数是一个回调函数,在这个回调函数中,我们可以使用 draft 参数来更新状态对象。

Loading

Loading 是一个 Rematch 插件,它可以帮助我们管理加载状态。在 Redux 中,我们通常使用一个布尔值来表示加载状态,例如:

// state.js
const initialState = {
  loading: false,
};

然而,这种方法存在一些问题。首先,我们需要在每个 reducer 中都手动更新加载状态。其次,我们需要在组件中手动检查加载状态。

Loading 插件提供了一种更好的方法来管理加载状态。它可以在 Rematch 的配置文件中启用:

// rematch.config.js
const config = {
  plugins: [
    // ...其他插件
    require('rematch-loading')(),
  ],
};

module.exports = config;

启用 Loading 插件后,我们就可以在 Redux 的 action 中使用它了。例如,以下代码使用 Loading 插件来更新加载状态:

// action.js
export const fetchTodos = () => {
  return {
    type: 'FETCH_TODOS',
    payload: {
      loading: true,
    },
  };
};

export const fetchTodosSuccess = (todos) => {
  return {
    type: 'FETCH_TODOS_SUCCESS',
    payload: {
      todos,
      loading: false,
    },
  };
};

export const fetchTodosError = (error) => {
  return {
    type: 'FETCH_TODOS_ERROR',
    payload: {
      error,
      loading: false,
    },
  };
};

在上面的代码中,fetchTodos() action 会将加载状态设置为 truefetchTodosSuccess()fetchTodosError() action 会将加载状态设置为 false

在组件中,我们可以使用 useLoading() hook 来获取加载状态。例如,以下代码使用 useLoading() hook 来显示一个加载指示器:

// component.js
import { useLoading } from 'rematch';

const Component = () => {
  const loading = useLoading();

  return (
    <div>
      {loading && <div>加载中...</div>}
      {!loading && <div>数据已加载</div>}
    </div>
  );
};

export default Component;

总结

Immer 和 Loading 是两个非常有用的 Rematch 插件,它们可以帮助我们更加轻松地管理状态。Immer 可以帮助我们以一种更安全、更简洁的方式来更新状态对象。Loading 可以帮助我们管理加载状态。

如果您正在使用 Rematch 来管理状态,那么我强烈建议您使用这两个插件。