Redux utils (三)

93 阅读4分钟

一、ReducerRegistry

ReducerRegistry是一个用于动态添加和替换reducer的工具。它允许我们在应用程序运行时添加新的reducer,而不需要在创建store时将它们全部添加到combineReducers中。

ReducerRegistry提供了以下方法:

  • getReducers(): 返回当前注册的所有reducers。
  • register(name, reducer): 注册一个新的reducer。
  • setReducers(reducers): 替换所有已注册的reducers。
  • replaceReducer(name, reducer): 替换指定名称的reducer。

使用ReducerRegistry,我们可以动态地添加和替换reducer,例如在应用程序中添加新的功能模块或在运行时更新现有reducer。

以下是一个使用ReducerRegistry的示例:

// src/reducerRegistry.js

class ReducerRegistry {
  constructor() {
    this._reducers = {};
    this._emitChange = null;
  }

  getReducers() {
    return { ...this._reducers };
  }

  register(name, reducer) {
    this._reducers = { ...this._reducers, [name]: reducer };
    if (this._emitChange) {
      this._emitChange(this.getReducers());
    }
  }

  setReducers(reducers) {
    this._reducers = reducers;
    if (this._emitChange) {
      this._emitChange(this.getReducers());
    }
  }

  replaceReducer(name, reducer) {
    this._reducers = { ...this._reducers, [name]: reducer };
    if (this._emitChange) {
      this._emitChange(this.getReducers());
    }
  }

  setChangeListener(listener) {
    this._emitChange = listener;
  }
}

const reducerRegistry = new ReducerRegistry();

export default reducerRegistry;

在创建store时,我们可以将ReducerRegistry的getReducers方法传递给combineReducers函数:

// src/store.js

import { createStore, combineReducers } from 'redux';
import ReducerRegistry from './reducerRegistry';


const reducer = ReducerRegistry.getReducers();

const store = createStore(reducer);

ReducerRegistry.setChangeListener((reducers) => {
  store.replaceReducer(combineReducers(reducers));
});

export default store;

在应用程序中注册新的reducer:

// src/newReducer.js
import ReducerRegistry from './reducerRegistry';

const initialState = { /* initial state */ };

ReducerRegistry.register(
    'app/xxx',
    (state = initialState, action) => {
      switch (action.type) {
        case 'SOME_ACTION':
          return { /* new state */ };
        default:
          return state;
      }
	 }
)

二、StateListenerRegistry

StateListenerRegistry是一个工具,用于注册和管理应用程序中的状态监听器。它可以让我们在状态更改时执行自定义操作,例如保存状态到本地存储或向服务器发送状态更改通知。

StateListenerRegistry提供了以下方法:

  • register(listener): 注册一个新的状态监听器。
  • unregister(listener): 注销一个状态监听器。

使用StateListenerRegistry,我们可以在应用程序中轻松地管理状态监听器,以便在状态更改时执行自定义操作。

以下是一个使用StateListenerRegistry的示例:

// src/stateListenerRegistry.js

class StateListenerRegistry {
  constructor() {
    this._listeners = new Set();
  }

  register(selector, listener, option) {
    this._listeners.add({selector, listener, option});
  }

  subscribe(store) {
    if (this._listeners.size) {
     store.subscribe(() => this.notifyListeners(store));
    }
  }

  unregister(listener) {
    this._listeners.delete(listener);
  }

  notifyListeners(store) {
    this._listeners.forEach((listener) => listener(store.getState()));
  }
}

const stateListenerRegistry = new StateListenerRegistry();

export default stateListenerRegistry;

在创建store时,我们可以在subscribe方法中注册状态监听器:

// src/store.js

import { createStore, combineReducers } from 'redux';
import ReducerRegistry from './reducerRegistry';
import StateListenerRegistry from './stateListenerRegistry';


const reducer = ReducerRegistry.getReducers();

const store = createStore(reducer);

ReducerRegistry.setChangeListener((reducers) => {
  store.replaceReducer(combineReducers(reducers));
});

StateListenerRegistry.subscribe(store);

export default store;

在应用程序中注册新的subscribe:

// src/newSubscribe.js
import StateListenerRegistry from './stateListenerRegistry';

const initialState = { /* initial state */ };


StateListenerRegistry.register(
    state => state['app/xxx'].xxx,
    (conference, { dispatch }, previousConference) => {
        if (conference && !previousConference) {
            // ...
        }
    }
);

三、PersistenceRegistry

PersistenceRegistry是一个工具,用于在Redux中启用状态持久化。它可以让我们在应用程序中轻松地将状态保存到本地存储或其他持久化存储中,并在应用程序重新加载时自动恢复状态。

PersistenceRegistry提供了以下方法:

  • register(persistConfig): 注册一个新的状态持久化配置。
  • unregister(key): 注销一个状态持久化配置。

使用PersistenceRegistry,我们可以在应用程序中轻松地管理状态持久化配置,以便在应用程序重新加载时自动恢复状态。

以下是一个使用PersistenceRegistry的示例:

// src/persistenceRegistry.js

import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';

class PersistenceRegistry {
  constructor() {
    this._persistConfigs = {};
  }

  register(persistConfig) {
    this._persistConfigs[persistConfig.key] = persistConfig;
  }

  unregister(key) {
    delete this._persistConfigs[key];
  }

  getReducers() {
    return Object.keys(this._persistConfigs).reduce((reducers, key) => {
      const persistConfig = this._persistConfigs[key];
      reducers[persistConfig.key] = persistReducer(persistConfig, persistConfig.reducer);
      return reducers;
    }, {});
  }

  getPersistConfig() {
    return Object.values(this._persistConfigs).map((persistConfig) => {
      return {
        ...persistConfig,
        storage,
      };
    });
  }
}

const persistenceRegistry = new PersistenceRegistry();

export default persistenceRegistry;

在创建store时,我们可以使用PersistenceRegistry来注册状态持久化配置:

// src/store.js

import { createStore, combineReducers } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import ReducerRegistry from './reducerRegistry';
import StateListenerRegistry from './stateListenerRegistry';
import PersistenceRegistry from './persistenceRegistry';


const rootReducer = ReducerRegistry.getReducers();
const persistedReducer = persistReducer(
  { key: 'root', storage },
  rootReducer
);

const store = createStore(persistedReducer);

ReducerRegistry.setChangeListener((reducers) => {
  store.replaceReducer(combineReducers(reducers));
});

StateListenerRegistry.subscribe(store);

export const persistor = persistStore(store, {
  ...persistenceRegistry.getPersistConfig(),
  // ...其他持久化配置
});

export default store;

在应用程序中注册新的persistence:

import PersistenceRegistry from './persistenceRegistry';

PersistenceRegistry.register({ key: 'xxx', reducer: xxxReducer });

四、MiddlewareRegistry

MiddlewareRegistry是一个工具,用于管理Redux中的中间件。它允许我们在应用程序中轻松添加、删除和替换中间件,以便在Redux流程中添加额外的逻辑。

MiddlewareRegistry提供以下方法:

  • register(middleware): 注册一个新的中间件。
  • unregister(key): 注销一个中间件。
  • getMiddlewares(): 获取当前所有注册的中间件。

以下是一个使用MiddlewareRegistry的示例:

// src/middlewareRegistry.js

class MiddlewareRegistry {
  constructor() {
    this._middlewares = {};
  }

  register(middleware) {
    this._middlewares[middleware.key] = middleware;
  }

  unregister(key) {
    delete this._middlewares[key];
  }

  getMiddlewares() {
    return Object.values(this._middlewares).map((middleware) => middleware.middleware);
  }
}

const middlewareRegistry = new MiddlewareRegistry();

export default middlewareRegistry;

在创建store时,我们可以使用MiddlewareRegistry来注册中间件:

// src/store.js

import { createStore, combineReducers, applyMiddleware } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import ReducerRegistry from './reducerRegistry';
import StateListenerRegistry from './stateListenerRegistry';
import PersistenceRegistry from './persistenceRegistry';
import MiddlewareRegistry from './middlewareRegistry';


const rootReducer = ReducerRegistry.getReducers();
const persistedReducer = persistReducer(
  { key: 'root', storage },
  rootReducer
);

const store = createStore(
  persistedReducer,
  applyMiddleware(...MiddlewareRegistry.getMiddlewares())
);

ReducerRegistry.setChangeListener((reducers) => {
  store.replaceReducer(combineReducers(reducers));
});

StateListenerRegistry.subscribe(store);

export const persistor = persistStore(store, {
  ...persistenceRegistry.getPersistConfig(),
  // ...其他持久化配置
});

export default store;

在应用程序中注册新的middleware:

import MiddlewareRegistry from './middlewareRegistry';

const xxxMiddleware = (store) => (next) => (action) => {
  console.log('Dispatching action:', action);
  const result = next(action);
  console.log('New state:', store.getState());
  return result;
};

xxxMiddleware.key = 'xxx';

// 注册
MiddlewareRegistry.register(xxxMiddleware);

// 注销
MiddlewareRegistry.unregister(xxxMiddleware.key);

ps:不吝赐教,有问题的可以一起探讨。