Redux 将旧状态迁移到新状态

问题描述 投票:0回答:1

我正在开发一个 React Native 应用程序。我使用persitCombineReducers 将减速器组合在一起设置。

其中一个切片进行了改造,现在具有新的结构。

这是旧结构:

interface OldAuthState {
  token?: string;
  expiresAt?: string;
  customer?: CustomerAuthFragment;
  numberOfTimeAskedForData?: number;
  lastDateAskedForData?: Date;
  dismissedQuizQuestions: string[];
}

这是我要迁移到的新结构:

interface AuthToken {
  token: string;
  expiresAt: string;
}

interface DataInfo {
  numberOfTimeAskedForData: number;
  lastDateAskedForData?: Date;
}

export interface AuthState {
  accessToken?: AuthToken;
  customer?: CustomerAuthFragment;
  dataInfo: DataInfo;
  dismissedQuizQuestions: string[];
}

经过一些在线研究,我发现使用 redux-persist 中的迁移和 createMigrate 函数是正确的方法。

感谢副驾驶,我最终得到了这个功能

const migrations = {
  1: (state: PersistedState) => {
    // Extract the old auth state.
    const oldAuthState = (state as any).auth as OldAuthState;

    // Initialize the new auth state based on the old one.
    const newAuthState: AuthState = {
      dataInfo: {
        numberOfTimeAskedForData: oldAuthState.numberOfTimeAskedForData ?? 0,
        lastDateAskedForData: oldAuthState.lastDateAskedForData,
      },
      accessToken: {
        token: oldAuthState.token ?? '',
        expiresAt: oldAuthState.expiresAt ?? '',
      },
      customer: oldAuthState.customer,
      dismissedQuizQuestions: oldAuthState.dismissedQuizQuestions,
    };

    // Return the new state.
    return {
      ...state,
      // Replace the old auth state with the new one.
      auth: newAuthState,
    };
  },
};

const migrate = createMigrate(migrations, { debug: process.env.NODE_ENV === 'development' });

我知道副驾驶给了我一些关于如何执行此操作的简单代码。另外,我不确定几点:

  • 它如何知道迁移过程中提供了哪种持久状态?
  • 如何将旧的状态结构与新的状态结构进行映射?

在网上,我只找到了有关如何向状态结构添加新值而不是更新整个状态的示例。另外,我在 redux 网站上没有找到任何关于此的文档。

react-native redux redux-persist
1个回答
0
投票

它如何知道迁移过程中提供了哪种持久状态?

这就是

version
持久配置发挥作用的地方。

{
  key: string,
  storage: Object,
  version?: number, // the state version as an integer (defaults to -1)
  blacklist?: Array<string>,
  whitelist?: Array<string>,
  migrate?: (Object, number) => Promise<Object>,
  transforms?: Array<Transform>,
  throttle?: number,
  keyPrefix?: string,
  debug?: boolean,
  stateReconciler?: false | StateReconciler,
  serialize?: boolean,
  writeFailHandler?: Function,
}

您可以有效地对要持久化的状态进行版本控制,并按顺序应用迁移,从持久化状态的版本到配置的当前版本。例如,如果有版本 0、1、2、3 和 4 的迁移,当前持久状态是版本 1,配置中的当前版本是版本 4,则应用迁移 2、3 和 4,在该命令,将状态更新到当前版本。

如何将旧的状态结构与新的状态结构进行映射?

无论您需要什么,这实际上都取决于您来处理。您可以添加新属性(具有有效的初始值),删除不再需要的属性,并在状态形状发生变化时根据需要移动状态。

据我所知,您的代码/逻辑似乎可以完成此任务。我认为代码 没有问题,除了

state
已经是
state
类型,并且可能已经定义了
auth
属性。我建议对类型进行版本控制,这样如果/当未来在相同的州区域进行迁移时,就可以轻松处理类型声明。

示例:

interface AuthState_V0 {
  token?: string;
  expiresAt?: string;
  customer?: CustomerAuthFragment;
  numberOfTimeAskedForData?: number;
  lastDateAskedForData?: Date;
  dismissedQuizQuestions: string[];
}

interface AuthToken {
  token: string;
  expiresAt: string;
}

interface DataInfo {
  numberOfTimeAskedForData: number;
  lastDateAskedForData?: Date;
}

export interface AuthState_V1 {
  accessToken?: AuthToken;
  customer?: CustomerAuthFragment;
  dataInfo: DataInfo;
  dismissedQuizQuestions: string[];
}
const migrations = {
  1: (state: PersistedState_V0) => {
    // Extract the old auth state.
    const oldAuthState = state.auth as AuthState_V0;

    // Initialize the new auth state based on the old one.
    const newAuthState: AuthState_V1 = {
      dataInfo: {
        numberOfTimeAskedForData: oldAuthState.numberOfTimeAskedForData ?? 0,
        lastDateAskedForData: oldAuthState.lastDateAskedForData,
      },
      accessToken: {
        token: oldAuthState.token ?? '',
        expiresAt: oldAuthState.expiresAt ?? '',
      },
      customer: oldAuthState.customer,
      dismissedQuizQuestions: oldAuthState.dismissedQuizQuestions,
    };

    // Return the new state.
    return {
      ...state,
      // Replace the old auth state with the new one.
      auth: newAuthState,
    };
  },
};
© www.soinside.com 2019 - 2024. All rights reserved.