State 的持久化怎么做?`@ngrx/store-localstorage`

145 阅读2分钟

State 的持久化是指将应用的状态(state)保存在浏览器的本地存储(localStorage)或会话存储(sessionStorage)中,以便页面刷新或浏览器关闭后,仍然能够恢复应用的状态。NgRx 中可以使用 @ngrx/store-localstorage 来实现这一目标。

@ngrx/store-localstorage

@ngrx/store-localstorage 是一个用于将 NgRx store 的状态同步到 localStoragesessionStorage 的库。通过该库,应用的状态可以持久化,在页面刷新后自动恢复。

使用示例

  1. 安装依赖
npm install @ngrx/store-localstorage
  1. 配置 store 与 localStorage

首先,你需要配置 @ngrx/store-localstorage 来同步 store 中的特定 slice(例如用户信息)到 localStorage

import { StoreModule } from '@ngrx/store';
import { storeFreeze } from 'ngrx-store-freeze';
import { StoreLocalStorageModule } from '@ngrx/store-localstorage';
import { appReducer } from './reducers';

@NgModule({
  imports: [
    StoreModule.forRoot(appReducer),
    StoreLocalStorageModule.forRoot({
      keys: ['user', 'settings'],  // 指定需要持久化的 slice
      rehydrate: true              // 从 localStorage 恢复 state
    })
  ]
})
export class AppModule {}
  1. 修改 Reducer

你可以选择哪些部分的 state 需要持久化。例如,我们只持久化 usersettings 的部分。

// user.reducer.ts
import { createReducer, on } from '@ngrx/store';
import { setUser } from './user.actions';

export const initialState = {
  name: '',
  email: ''
};

const _userReducer = createReducer(
  initialState,
  on(setUser, (state, { user }) => ({ ...state, ...user }))
);

export function userReducer(state, action) {
  return _userReducer(state, action);
}
  1. 从 localStorage 恢复状态

当应用启动时,@ngrx/store-localstorage 会自动从 localStorage 恢复已持久化的 state,并重新加载到 store。


手动实现 State 持久化

如果你不想使用 @ngrx/store-localstorage,你也可以手动实现一个持久化方案:

  1. 自定义 reducer 或 effect,在应用启动时检查 localStorage 是否有存储的状态,并恢复。
  2. 使用 ngrx-store-persist:手动订阅 store,保存 state 到 localStorage
import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppState } from './reducers';
import { loadUser } from './user.actions';

@Injectable({
  providedIn: 'root',
})
export class PersistStateService {

  constructor(private store: Store<AppState>) {}

  init() {
    const savedUser = localStorage.getItem('user');
    if (savedUser) {
      this.store.dispatch(loadUser({ user: JSON.parse(savedUser) }));
    }
  }

  saveState(user: any) {
    localStorage.setItem('user', JSON.stringify(user));
  }
}

在组件中监听状态变化并保存:

this.store.select('user').subscribe(user => {
  this.persistStateService.saveState(user);
});

总结

方案优点缺点
@ngrx/store-localstorage配置简单,自动同步 store 与 localStorage只适用于小型应用,持久化所有 state 可能增加性能负担
手动实现持久化灵活,适用于不同需求需要更多的代码和配置

推荐使用:如果只是简单的持久化某些 state,@ngrx/store-localstorage 可以非常高效;而如果需要更多自定义功能(例如加密、特定逻辑),可以选择手动实现。