当前位置: 首页 > 工具软件 > redux-persist > 使用案例 >

redux-persist_迁移状态时如何使用Redux Persist

蔚和安
2023-12-01

redux-persist

Storage has always been an integral part of building apps. While building a webapp for our company, I needed a way to persist my states in storage which was reliable, easy to use, and configurable based on the requirements.

存储一直是构建应用程序不可或缺的一部分。 在为我们的公司构建Web应用程序时,我需要一种将状态保持在存储中的方法,该方法可靠,易于使用并且可以根据要求进行配置。

Thankfully this library was the answer to all my problems!

幸运的是,这个库是我所有问题的答案!

This article is based on a problem I faced while working on a project. Let us dive deep and understand how the library helped me solve it.

本文基于我在项目中遇到的问题。 让我们深入了解图书馆如何帮助我解决它。

If you haven’t already used redux-persist, then do read the docs, as they’re self-explanatory. If you want to know why you should use this library, go through this article — it is a great intro by the author himself!

如果您尚未使用redux-persist ,那么请阅读文档,因为它们是不言自明的。 如果您想知道为什么要使用该库,请阅读本文 -这是作者本人的精彩介绍!

问题 (Problem)

Let’s take an example where I wanted to persist a reducer in my localStorage:

让我们举个例子,我想在我的localStorage中保留一个reducer:

//Reducer
reducerA: {  
    engine: {    
        model: "F5AAA",    
        manufacturer: "Ferrari"  
    },  
    tyre: {    
        model: "T123",   
		manufacturer: "MRF",    
		owner: {      
            details: {        
                name: "Zack",        
				age: "26"            
            }    
        }  
    },  
	condition: "prime"
}
//View
class TestComponent extends React.Component {  
    render() {    
        const model = someStateOfReducerA.tyre.model    
        const manufacturer = someStateOfReducerA.tyre.manufacturer
        
		return (      
            <div>{model}</div>      
            <div>{manufacturer}</div>    
        )  
    }
}

//Reducer in localStorage
reducerA: {  
    engine: {    
        model: "F5AAA",    
		manufacturer: "Ferrari"  
    },  
	tyre: {    
        model: "T123",    
		manufacturer: "MRF",    
		owner: {      
            details: {        
                name: "Zack",        
				age: "26"            
            }    
        }  
    },  
	condition: "prime"
}

Now this reducer has persisted in our client’s device. So what will happen if I introduce a new key to our reducerA?

现在,该减速器已保留在我们客户的设备中。 那么,如果我为我们的reducerA引入新的密钥,将会发生什么?

reducerA: {  
	engine: {    
    	model: "F5AAA",    
	    manufacturer: "Ferrari"  
   	},  
    tyre: {    
    	model: "T123",    
        manufacturer: "MRF",    
        owner: {      
        	details: {        
            	name: "Zack",        
                age: "26",        
                address: "CA" // NEW KEY ADDED
			}    
		}  
	},  
    condition: "prime"
}

Let’s say we have a view which renders the value of our newly introduced key:

假设我们有一个视图,该视图呈现了我们新引入的键的值:

//View with new key address
class TestComponent extends React.Component {  
    render() {    
        const model = someStateOfReducerA.tyre.model    
        const manufacturer = someStateOfReducerA.tyre.manufacturer    
        const address = someStateOfReducerA.tyre.owner.details.address
        
		return (      
            <div>{model}</div>      
            <div>{manufacturer}</div>      
            <div>{address}</div>
		)  
    }
}

When I load my application with the newly introduced key, the rendering of our view fails. It throws an error where it states:

当我用新引入的密钥加载应用程序时,视图的呈现失败。 它在以下位置引发错误:

Cannot render address of undefined

This happened because the client’s storage is in sync with the rootReducer initialized during our app reload.

发生这种情况是因为客户端的存储与我们重新加载应用程序时初始化的rootReducer同步。

Even though we introduced the new key, the client’s storage never received it. It initializes our rootReducer with the old values in storage, where the address never existed, and causes the rendering of our component to fail.

即使我们引入了新密钥,客户端的存储也从未收到过。 它使用存储区中不存在该地址的旧值来初始化rootReducer,并使组件渲染失败。

(Solution)

This leads to a well-known concept: the migration of the database.

这导致了一个众所周知的概念:数据库的迁移。

A schema migration is performed on a database whenever it is necessary to update or revert that database’s schema to some newer or older version. Migrations are performed programmatically by using a schema migration tool — Wikipedia

每当需要将数据库的架构更新或还原到较新或较旧的版本时,就会对数据库执行架构迁移迁移是通过使用模式迁移工具进行编程- 维基百科

LocalStorage is in fact a small database of key value pairs. Redux Persist does it beautifully. If you look at a project initialized with this library, it already uses a default version -1. Take a look below at the screenshot taken from the application tab in the Chrome dev tool.

实际上,LocalStorage是键值对的小型数据库。 Redux Persist做得很漂亮。 如果查看使用此库初始化的项目,则该项目已使用默认版本-1 。 下面看一下从Chrome开发工具的“应用程序”标签中截取的屏幕截图。

This is really good! The library already maintains a default version for us, so that we can incorporate the migration feature in the future.

这真的很好! 该库已经为我们维护了一个默认版本,以便将来我们可以合并迁移功能。

The key is to configure your persist configuration in your rootReducer.

关键是在rootReducer中配置持久配置。

export const persistConfig = {  
    key: 'testApp',  
    version: 0, //New version 0, default or previous version -1  
    storage,  
    debug: true,  
    stateReconciler: autoMergeLevel2,  
    migrate: createMigrate(migrations, { debug: true })
}

It is important that we update the version to 0, so that it migrates our storage from -1 to 0.

重要的是,我们将版本更新为0,以便将存储从-1迁移到0。

Next, we write the migration to let our storage know that there is an update.

接下来,我们编写迁移操作,以使我们的存储设备知道有更新。

const migrations = {  
    0: (state) => {    
        return {      ...
			state,      
			tyre: {        ...
				state.tyre,        
				owner: {          ...
					state.tyre.owner,          
					details: {
                        state.tyre.owner.details,
                        address: "CA" //New Key added for migration
                    }
				}      
			}    
		}  
    }
}

The migrations are then used in our persist config mentioned above:

然后在上面提到的持久配置中使用迁移

migrate: createMigrate(migrations, { debug: true })

Thus, when we reload our application, our application goes through a reconciliation phase where the storage is brought in sync with the newly-updated reducer.

因此,当我们重新加载应用程序时,我们的应用程序将进入协调阶段,在此阶段,存储将与新更新的reducer同步。

结论 (Conclusion)

The configuration above will always keep the application updated on the client side when you release new versions. It is very important that we are careful about this when making offline first apps.

当您发布新版本时,以上配置将始终在客户端上更新应用程序。 制作离线首批应用程序时,请务必谨慎,这一点非常重要。

It is simple once you understand the basic concept and technique to do it. I hope this article helped you understand the importance of managing versions of your states in storage :)

一旦您了解了执行此操作的基本概念和技术,它就很简单。 我希望本文能帮助您了解管理存储中状态版本的重要性:)

Follow me on twitter to get more updates regarding new articles and to stay updated in latest frontend developments. Also share this article on twitter to help others know about it. Sharing is caring ^_^.

推特上关注我,以获取有关新文章的更多更新,并随时了解最新的前端开发。 也可以在Twitter上分享此文章,以帮助其他人了解它。 分享是关怀^ _ ^。

一些有用的资源 (Some helpful resources)

  1. https://github.com/rt2zz/redux-persist/blob/master/docs/api.md

    https://github.com/rt2zz/redux-persist/blob/master/docs/api.md

  2. https://medium.com/@clrksanford/persist-ence-is-key-using-redux-persist-to-store-your-state-in-localstorage-ac6a000aee63

    https://medium.com/@clrksanford/persist-ence-is-key-using-redux-persist-to-store-your-state-in-localstorage-ac6a000aee63

  3. https://medium.com/async-la/redux-persist-your-state-7ad346c4dd07

    https://medium.com/async-la/redux-persist-your-state-7ad346c4dd07

翻译自: https://www.freecodecamp.org/news/how-to-use-redux-persist-when-migrating-your-states-a5dee16b5ead/

redux-persist

 类似资料: