@abhinavzspace/redux-pouchdb-plus 中文文档教程

发布于 8年前 浏览 20 项目主页 更新于 3年前

Redux PouchDB Plus

About

Redux PouchDB PlusRedux 存储与 PouchDB 同步 数据库。

此代码深受 Vicente de Alencar 的 redux-pouchdb 启发(并重用了一些代码)。 所以所有的荣誉都归功于他。 重写是必要的,以允许以下额外功能:

  • Have different Pouch databases for different reducers.
  • Allow to switch databases dynamically.
  • Support for Immutable states beside pure Javascript types.
  • Provide several callbacks (when initialization and database access happens).

使用 tape 对代码进行了很好的测试。

Usage

General setup

您希望保留的缩减器应该使用此高阶缩减器 (persistentReducer) 进行增强。

import { persistentReducer } from 'redux-pouchdb-plus';

const counter = (state = {count: 0}, action) => {
  switch(action.type) {
  case INCREMENT:
    return { count: state.count + 1 };
  case DECREMENT:
    return { count: state.count - 1 };
  default:
    return state;
  }
};

const finalReducer = persistentReducer(counter);

与其他增强器组成一个存储增强器 (persistentStore) 以初始化持久性。

import { persistentStore } from 'redux-pouchdb-plus';

const db = new PouchDB('dbname');

//optional
const applyMiddlewares = applyMiddleware(
  thunkMiddleware,
  loggerMiddleware
);

const createStoreWithMiddleware = compose(
  applyMiddlewares,
  persistentStore({db})
)(createStore);

const store = createStoreWithMiddleware(finalReducer, initialState);

您还可以为这个减速器提供一个特定的数据库(它优先于 向商店提供的数据库)。

const db2 = new PouchDB('another_dbname');
const finalReducer = persistentReducer(counter, {db: db2});

Switching databases during runtime

您还可以提供一个返回数据库连接器而不是 连接器本身。 这使得在运行时动态切换数据库成为可能。

import { reinit } from 'redux-pouchdb-plus';

let dbChoice = 1;
const db = (reducerName, store, additionalOptions) => {
  if (dbChoice === 1)
    return new PouchDB('dbname1');
  else
    return new PouchDB('dbname2');
}

// uses 'dbname1' database
const finalReducer = persistentReducer(counter, {db});

// switch to 'dbname2' database
dbChoice = 2;
// reinitialize reducer counter
store.dispatch(reinit('counter'));
// reinitialize all reducers
store.dispatch(reinit());

Check if database is in sync

使用 inSync 方法,您可以检查持久性的所有状态是否发生变化 reducer 被保存到数据库中,或者是否有一些正在进行的保存。

import { inSync } from 'redux-pouchdb-plus';

if (inSync()) {
  // do something if the reducer states and the database are in sync
}

Use Immutable js states

您可以使用 Immutable.js 状态 在你的减速器中。 如果 初始状态是 Immutable.js 数据类型

// automatically serializes Immutable.js data types to PouchDB
// when the initial state is an Immutable
const counter = (state = Immutable.Map({count: 0}), action) => {
  switch(action.type) {
  case INCREMENT:
    return { count: state.count + 1 };
  case DECREMENT:
    return { count: state.count - 1 };
  default:
    return state;
  }
};

const finalReducer = persistentReducer(counter);

甚至可以混合不可变和纯 Javascript 数据 在内部 transit-immutable-js 用于序列化到数据库。 只要确保顶部 reducer 的状态容器是不可变的。

// this is a valid state
Immutable.Map({x: [1, 2, 3]});

// this will open the doors to hell
[1, 2, Immutable.Map({x: 3})];

Provided callback functions

您可以提供以下回调函数作为附加选项 persistentReducerpersistentReducer

// example for persistentStore, but works the same for persistentReducer function.
persistentStore(counter, {
  db,
  onInit: (reducerName, reducerState, store) => {
    // Called when this reducer was initialized
    // (the state was loaded from or saved to the
    // database for the first time or after a reinit action).
  },
  onUpdate: (reducerName, reducerState, store) => {
    // Called when the state of reducer was updated with
    // data from the database.
    // Cave! The store still contains the state before
    // the updated reducer state was applied to it.
  },
  onSave: (reducerName, reducerState, store) => {
    // Called every time the state of this reducer was
    // saved to the database.
  }
});

此外,您可以在调用的商店上提供 onReady 回调 每次所有持久性 recuders 完成初始化。

persistentStore(counter, {
  db,
  onReady: (store) => {
    // Called when all reducers are initialized (also after
    // a reinit for all reducers is finished).
  }
}

Notes

当前的行为是为每个持久化的 reducer 准备一个文档,如下所示:

{
  _id: 'reducerName', // the name the reducer function
  state: {}|[], // the state of the reducer
  _rev: '' // pouchdb keeps track of the revisions
}

Redux PouchDB Plus

About

Redux PouchDB Plus synchronizes a Redux store with a PouchDB database.

This code is heavily inspired (and some code reused) by Vicente de Alencar's redux-pouchdb. So all Kudos to him. The rewrite was necessary to allow the following extras:

  • Have different Pouch databases for different reducers.
  • Allow to switch databases dynamically.
  • Support for Immutable states beside pure Javascript types.
  • Provide several callbacks (when initialization and database access happens).

The code is quite well tested using tape.

Usage

General setup

The reducers you wish to persist should be enhanced with this higher order reducer (persistentReducer).

import { persistentReducer } from 'redux-pouchdb-plus';

const counter = (state = {count: 0}, action) => {
  switch(action.type) {
  case INCREMENT:
    return { count: state.count + 1 };
  case DECREMENT:
    return { count: state.count - 1 };
  default:
    return state;
  }
};

const finalReducer = persistentReducer(counter);

Compose a store enhancer (persistentStore) with other enhancers in order to initialize the persistence.

import { persistentStore } from 'redux-pouchdb-plus';

const db = new PouchDB('dbname');

//optional
const applyMiddlewares = applyMiddleware(
  thunkMiddleware,
  loggerMiddleware
);

const createStoreWithMiddleware = compose(
  applyMiddlewares,
  persistentStore({db})
)(createStore);

const store = createStoreWithMiddleware(finalReducer, initialState);

You may also provide a specific database for this reducer (it is prioritized over the provided database to the store).

const db2 = new PouchDB('another_dbname');
const finalReducer = persistentReducer(counter, {db: db2});

Switching databases during runtime

You may also provide a function that return a database connector instead of the connector itself. This makes it possible to switch databases dynamically during runtime.

import { reinit } from 'redux-pouchdb-plus';

let dbChoice = 1;
const db = (reducerName, store, additionalOptions) => {
  if (dbChoice === 1)
    return new PouchDB('dbname1');
  else
    return new PouchDB('dbname2');
}

// uses 'dbname1' database
const finalReducer = persistentReducer(counter, {db});

// switch to 'dbname2' database
dbChoice = 2;
// reinitialize reducer counter
store.dispatch(reinit('counter'));
// reinitialize all reducers
store.dispatch(reinit());

Check if database is in sync

With the inSync method you can check if all state changes of persistent reducers are saved to the database or if there is some saving in progress.

import { inSync } from 'redux-pouchdb-plus';

if (inSync()) {
  // do something if the reducer states and the database are in sync
}

Use Immutable js states

You can use Immutable.js states in your reducers. This works automatically if the initial state is an Immutable.js data type.

// automatically serializes Immutable.js data types to PouchDB
// when the initial state is an Immutable
const counter = (state = Immutable.Map({count: 0}), action) => {
  switch(action.type) {
  case INCREMENT:
    return { count: state.count + 1 };
  case DECREMENT:
    return { count: state.count - 1 };
  default:
    return state;
  }
};

const finalReducer = persistentReducer(counter);

It is even possible to mix immutable and plain Javascript data as internally transit-immutable-js is used for serialization to the database. Just make sure that the top state container of the reducer is an immutable.

// this is a valid state
Immutable.Map({x: [1, 2, 3]});

// this will open the doors to hell
[1, 2, Immutable.Map({x: 3})];

Provided callback functions

You may provide the following callback functions as addition options to persistentReducer or persistentReducer:

// example for persistentStore, but works the same for persistentReducer function.
persistentStore(counter, {
  db,
  onInit: (reducerName, reducerState, store) => {
    // Called when this reducer was initialized
    // (the state was loaded from or saved to the
    // database for the first time or after a reinit action).
  },
  onUpdate: (reducerName, reducerState, store) => {
    // Called when the state of reducer was updated with
    // data from the database.
    // Cave! The store still contains the state before
    // the updated reducer state was applied to it.
  },
  onSave: (reducerName, reducerState, store) => {
    // Called every time the state of this reducer was
    // saved to the database.
  }
});

Additionally you may provide an onReady callback on the store that is called every time all persistent recuders finished the initialization.

persistentStore(counter, {
  db,
  onReady: (store) => {
    // Called when all reducers are initialized (also after
    // a reinit for all reducers is finished).
  }
}

Notes

The current behavior is to have one document for each persisted reducer that looks like:

{
  _id: 'reducerName', // the name the reducer function
  state: {}|[], // the state of the reducer
  _rev: '' // pouchdb keeps track of the revisions
}
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文