react-native - 如果缓存数据与新的 reducers 结构不一致,我们如何防止移动应用程序崩溃?
问题描述
我目前正在使用 React Native 和 Redux 开发电子商务管理移动应用程序。我们使用 redux-persist 持久化数据。这带来了缓存数据的绝佳体验,这是离线优先开发的原则。
但是在移动世界环境中可能会发生错误。
假设我有一个名为“产品”的减速器。该 reducer 只是一个包含产品对象的数组。用户登录,现在该 reducer 中的数据被持久化。后来,我的开发团队决定在“产品”reducer 上使用新结构更新移动应用程序。用户的应用程序得到更新,现在持久化/缓存的数据与导致应用程序崩溃的新“产品”reducer 结构不一致。
我可能错了,但这是一个可能存在的实际错误吗?如果是这样,什么是解决方法或解决方案?
谢谢!
解决方案
这是一个可能存在的潜在错误,我同意,因为它发生在我身上两次,我发现了一些可能对你有帮助的东西。崩溃的原因取决于存储在磁盘上的内容以及您的代码使用的内容,让我解释一下。
//let say we have a reducer
function ProductReducer(
state={
products:[],
fetching:false
},action){
switch(){......}
}
// lets say we have a combine reducer
combineReducers({
products: ProductReducer
})
//let say we have a component that consums this products
function RenderProducts(){
const {products, fetching} = useSelector((store)=>({
products: store.products.products,
fetching: store.products.fetching,
}))
return (
<View>
{
fetching && (
<Text>
loading...
</Text>
)
}
{products.map((item)=>
<View>
<Text>
{item.name}
</Text>
</View>)
}
</View>
)
}
现在我们的更新看起来像这样
// Now lets new reducer be
function ProductReducer(
state={
productsList:[],
fetchingProduct:false
},action){
switch(){......}
}
// Now our Render component becomes
function RenderProducts(){
const {products, fetching} = useSelector((store)=>({
products: store.products.productsList,
fetching: store.products.fetchingProduct,
}))
return (
<View>
{
fetching && (
<Text>
loading...
</Text>
)
}
{products.map((item)=>
<View>
<Text>
{item.name}
</Text>
</View>)
}
</View>
) }
现在第二个代码将导致崩溃崩溃,原因之一是您将尝试在未定义的对象上调用 .map,为什么会发生这种情况,简单的原因如下所示
// Intial store
const store = {
products:{
products:[], // array of products
fetching: false,
}
}
**这是我们作为 JSON 字符串存储在磁盘上的存储 ** 在我们更新到 REDUCER 之后,我们的存储保持不变,在我们从服务器获取数据之前,以便我们的 reducer 可以将我们的更新写入磁盘,渲染产品组件正在尝试应用我们的更新和崩溃
解决方案
您可以清除商店 // 您不希望这样做,因为包括令牌和重要信息在内的所有存储数据都将丢失,用户将重新启动应用程序
了解了这个问题后,您现在可以有多种解决方法,例如在渲染组件之前分派一个操作以在磁盘上强制执行迁移。这就是我要应用更新的意思,我会这样做...
function ProductReducer( state={ productsList:[], fetchingProduct:false },action){ switch(action.type){ case 'MIGRATING':{ if(store.products){ // checking if products exist on the products reducer this will handle updates and new installs state = {...state,productsList: state.products,fetchingProduct:state.fetching} } return state; } } }
这会将更改写入磁盘,但请确保在渲染组件之前运行它我将为所有减速器执行此操作
- 我将编写我的组件以始终检查他们正在读取的数据是否可用,或者分别为字符串、数组和对象呈现空数据,如 ''、[]、{}
推荐阅读
- facebook - 如何不将 Facebook 聊天机器人与正常对话混为一谈
- java - 创建 Do-While 循环后修复 java.lang.NullPointerException
- python - Pandas 数据框无法从 CSV 中绘制 x 值
- python - 如何在 python 脚本中获取两个 svn 修订版的完整上下文差异?
- python - Jinja 模板引擎过滤器
- protocol-buffers - google.protobuf.Empty 对向后兼容有危险吗?
- android - android centerCrop 比例与顶部开始对齐
- c# - 使用内联连接检查 IsNullOrEmpty
- sql - SQL中的空位列
- delphi - Delphi WinINet Api 编码