我正在开发一个React Native应用程序.我有一个使用persitCombineReducers设置的reducers组合.

其中一个切片进行了 retrofit ,现在有了新的 struct .

这是旧 struct :

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

这是我想要迁移到的新 struct :

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

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

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

经过一些在线研究,我发现使用redux—persistent中的迁移和review Migrate函数是可行的.

多亏了副驾驶,我终于有了这个功能

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' });

我知道副驾驶给了我一些简单的代码来做这件事.另外,我不确定几点:

  • 它如何知道在迁移期间提供了哪个持久化状态?
  • 如何将以前的国家 struct 与新的国家 struct 相对应?

在网上,我只找到了一些示例,说明如何向状态 struct 添加新值,而不是更新整个状态.另外,我在redux网站上找不到任何关于这个的文档.

推荐答案

它如何知道在迁移期间提供了哪个持久化状态?

persist configuration中的version开始发挥作用.

{
  key: string,
  s到rage: Object,
  version?: number, // the state version as an integer (defaults 到 -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,
}

您可以有效地对正在持久化的状态进行版本化,并按照从持久化状态版本到当前配置版本的顺序应用migrations.例如,如果存在版本0、1、2、3和4的迁移,当前持久状态为版本1,配置中的当前版本为版本4,则迁移2、3和4将按此顺序应用,以将状态更新为当前版本.

如何将以前的国家 struct 与新的国家 struct 相对应?

这件事真的由你来处理,无论你需要什么.您可以添加新属性(with valid initial values),删除不再需要的属性,并在状态形状改变时根据需要移动状态.

从我可以告诉你的代码/逻辑,它似乎完成了这一点.我认为代码other than没有问题,state已经是state类型,应该已经定义了auth属性.我建议对类型进行版本控制,以便如果/当将来在相同的状态区域中有迁移时,处理类型声明就很容易了.

示例:

interface AuthState_V0 {
  到ken?: string;
  expiresAt?: string;
  cus到mer?: Cus到merAuthFragment;
  numberOfTimeAskedForData?: number;
  lastDateAskedForData?: Date;
  dismissedQuizQuestions: string[];
}

interface AuthToken {
  到ken: string;
  expiresAt: string;
}

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

export interface AuthState_V1 {
  accessToken?: AuthToken;
  cus到mer?: Cus到merAuthFragment;
  dataInfo: DataInfo;
  dismissedQuizQuestions: string[];
}
const migrations = {
  1: (state: PersistedState) => {
    // 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: {
        到ken: oldAuthState.到ken ?? '',
        expiresAt: oldAuthState.expiresAt ?? '',
      },
      cus到mer: oldAuthState.cus到mer,
      dismissedQuizQuestions: oldAuthState.dismissedQuizQuestions,
    };

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

React-native相关问答推荐

react 本机中的TextInput对齐中的长文本

try 使用JWT-DECODE解码令牌时出错

为什么当我更换屏幕时playground 音乐不会停止?

RTK 查询显示互联网何时关闭?

react native 如何更新倒置平面列表的数组中的项目

'未能找到 React 根视图的片段' React Native Android RNScreens

react-native 根据状态隐藏显示按钮

ReactNative:在所有组件和操作之间共享 sqlite 实例的最佳方法

react平面列表渲染项

Eslint 错误,configuration for rule "import/no-cycle" is invalid

如何手动在抽屉导航底部添加额外的元素(如注销按钮)?

如何使用 InteractionManager.runAfterInteractions 使导航器过渡更快

如何在 React Native 中访问原生 UI 组件的实例方法

React Native Maps:标记图像不显示在 react-native-maps 中使用自定义标记

React native Redux - 对象不是构造函数(判断'new ctor(props context)')

Android 构建错误AndroidManifest.xml requires a placeholder substitution

如何将 Crashlytics 与 React Native 应用程序集成

React Native 将状态中的数组值应用为 Picker 项

react-native-webview :对于 iOS 文本太小

Expo在使用Windows 10的android模拟器上运行