I am working on a React Native app. I have a combination of reducers set up together using persitCombineReducers.
One of the slices had a revamp and now has a new structure.
This is the old structure :
interface OldAuthState {
token?: string;
expiresAt?: string;
customer?: CustomerAuthFragment;
numberOfTimeAskedForData?: number;
lastDateAskedForData?: Date;
dismissedQuizQuestions: string[];
}
This is the new structure that I want to migrate to:
interface AuthToken {
token: string;
expiresAt: string;
}
interface DataInfo {
numberOfTimeAskedForData: number;
lastDateAskedForData?: Date;
}
export interface AuthState {
accessToken?: AuthToken;
customer?: CustomerAuthFragment;
dataInfo: DataInfo;
dismissedQuizQuestions: string[];
}
After some research online, I found out that using migrations and createMigrate function from redux-persist is the way to go.
Thanks to copilot I ended up with this function
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' });
I am aware that copilot gives me some naive code on how to do this. Also, I am unsure about a few points:
- How will it know which persisted state is being provided during the migration?
- How to map the former state structure with the new one?
Online, I only found examples on how to add a new value to the state structure and not updating the whole state. Plus I don't find any documentation about this on redux website.
This where the
versionof the persist configuration comes into play.You effectively version the state you are persisting, and the migrations are applied, in order, from the version of the persisted state to the current version of the configuration. Example, if there are migrations for versions 0, 1, 2, 3, and 4, the currently persisted state is version 1, and the current version in the configuration is version 4, then migrations 2, 3, and 4 are applied, in that order, to update the state to the current version.
This one is really up to you to handle, however you need. You can add new properties (with valid initial values), delete properties that are no longer needed, and move state around as you deem necessary when the state shape changes.
From what I can tell of your code/logic it appears to accomplish this. I see no issue with the code other than
stateis already thestatetype and should likely already have theauthproperty defined. I'd suggest versioning the types so if/when there are future migrations in the same areas of state that it's easy to handle type declarations.Example:
to