Uppy 自定义存储
如果你的应用使用了如 Redux 这样的状态管理库,那么让 Uppy 将其状态存储在其中会非常有用 —— 这样,你就可以像编写应用中其他组件一样编写自定义上传器 UI 组件。
Uppy 提供了两个状态管理解决方案(存储):
@uppy/store-default
,基于对象的基本存储。@uppy/store-redux
,使用 Redux 存储中的一个键。
你还可以使用第三方存储:
- uppy-store-ngrx,在 Ngrx 存储中保存 Uppy 状态,用于 Angular 应用。
使用存储
要使用存储,将实例传递给 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)
- 当状态更改时调用listener
。listener
是一个应接收三个参数的函数:(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 包以获取更多灵感。