项目
版本

Uppy 自定义存储

如果你的应用使用了如 Redux 这样的状态管理库,那么让 Uppy 将其状态存储在其中会非常有用 —— 这样,你就可以像编写应用中其他组件一样编写自定义上传器 UI 组件。

Uppy 提供了两个状态管理解决方案(存储):

  • @uppy/store-default,基于对象的基本存储。
  • @uppy/store-redux,使用 Redux 存储中的一个键。

你还可以使用第三方存储:

使用存储

要使用存储,将实例传递给 Uppy 构造函数中的 store 选项:

import DefaultStore from "@uppy/store-default";

const uppy = new Uppy({
  store: new DefaultStore(),
});

DefaultStore

Uppy 默认使用 DefaultStore!你不需要做任何事情来使用它。它不接受任何选项。

ReduxStore

ReduxStore 在现有的 Redux 存储中的某个键上存储 Uppy 的状态。ReduxStore 发送 uppy/STATE_UPDATE 操作来更新状态。当 Redux 中的状态发生变化时,它会通知 Uppy。这样,你可以享受到 Redux 的大部分好处,包括对 Redux Devtools 和时间旅行的支持!

查看我们的 Redux 示例 获取一个工作演示。

opts.store

传递一个从 Redux.createStore 创建的 Redux 存储实例。这个实例应该已经挂载了 Uppy 的还原器。

opts.id

默认情况下,ReduxStore 假定 Uppy 状态存储在 state.uppy[id] 键上。id 是由存储构造函数随机生成的,但可以通过传递 id 选项来指定,以便使其可预测。

ReduxStore({
  store,
  id: "avatarUpload",
});

opts.selector

如果你不想将 Uppy 状态完全存储在 state.uppy 键下,可以使用 ReduxStore 构造函数的 selector 选项告诉它在哪里找到状态:

const uppy = new Uppy({
  store: ReduxStore({
    store,
    id: "avatarUpload",
    selector: (state) => state.pages.profile.uppy.avatarUpload,
  }),
});

请注意,当你指定自定义选择器时,必须 也指定自定义存储 ID。存储 ID 告诉还原器应该将 Uppy 的状态放在哪个属性中。在示例中,我们将 ID 设置为 avatarUpload,并从 [reducer mount path].avatarUpload 获取状态。

如果你的应用使用了 reselect,它的选择器与此很好地配合!

实现存储

Uppy 存储是一个具有三个方法的对象。

  • getState() - 返回当前状态对象。
  • setState(patch) - 将对象 patch 合并到当前状态中。
  • subscribe(listener) - 当状态更改时调用 listenerlistener 是一个应接收三个参数的函数:(prevState, nextState, patch)

subscribe() 方法应返回一个函数,用于 “取消订阅”(移除)listener

默认存储实现例如看起来像这样:

function createDefaultStore() {
  let state = {};
  const listeners = new Set();

  return {
    getState: () => state,
    setState: (patch) => {
      const prevState = state;
      const nextState = { ...prevState, ...patch };

      state = nextState;

      listeners.forEach((listener) => {
        listener(prevState, nextState, patch);
      });
    },
    subscribe: (listener) => {
      listeners.add(listener);
      return () => listeners.remove(listener);
    },
  };
}

如果需要,让用户通过函数调用来传递选项的这种模式是推荐的。

参阅 @uppy/store-default 包以获取更多灵感。

在本文档中