Umi中使用model的useModel钩子时,为什么组件重新渲染后数据丢失了?

程哲 阅读 4

我在Umi项目里用model管理购物车数据,通过useModel获取数据后,页面跳转再返回时发现购物车数据突然清空了,但本地存储里还有记录。尝试过在model里加persist配置和手动写localStorage都没解决,控制台也没有报错,这是怎么回事?

model定义是这样的:

export default {
  state: { cart: [] },
  effects: {
    async addProduct(payload, { put }) {
      await axios.post('/api/cart', payload);
      put({ type: 'saveProduct', payload });
    }
  },
  reducers: {
    saveProduct(state, action) {
      return { ...state, cart: [...state.cart, action.payload] };
    }
  }
}

组件里这样调用:

const { cart } = useModel('cart');
// 页面跳转到详情页再返回时,cart数组变为空了

难道useModel的值不是持久化的?

我来解答 赞 5 收藏
二维码
手机扫码查看
1 条解答
IT人福萍
问题出在model的状态管理上,Umi的model默认是不持久化的,页面刷新或者组件卸载后状态就会重置。你提到跳转页面再返回时数据丢失,这是因为组件重新挂载时model的状态被重置了,虽然你尝试了persist配置,但可能没配对。

代码给你,先改model,加上persist配置,确保状态能存到localStorage并且自动恢复:

export default {
state: { cart: [] },
subscriptions: {
setup({ dispatch, history }) {
// 初始化时从localStorage读取数据
const localCart = JSON.parse(localStorage.getItem('cart') || '[]');
dispatch({ type: 'saveCart', payload: localCart });
}
},
effects: {
async addProduct(payload, { put }) {
await axios.post('/api/cart', payload);
put({ type: 'saveProduct', payload });
}
},
reducers: {
saveProduct(state, action) {
const newCart = [...state.cart, action.payload];
localStorage.setItem('cart', JSON.stringify(newCart)); // 同步到localStorage
return { ...state, cart: newCart };
}
}
};


然后在组件里调用的时候不用改太多,但建议加个检查逻辑,防止意外情况:

import { useModel } from 'umi';

export default function Cart() {
const { cart, addProduct } = useModel('cart');

if (!Array.isArray(cart)) {
console.warn('购物车数据异常,已重置为空数组');
return null; // 或者根据需求处理
}

return (

购物车



    {cart.map((item, index) => (
  • {item.name}

  • ))}



);
}


关键点是:
1. 在model里用localStorage手动同步数据,确保状态持久化
2. 组件加载时检查数据是否正常,避免渲染异常
3. persist配置需要正确设置,但如果你不确定怎么配,手动存localStorage更可靠

吐槽一句,状态管理这玩意儿,尤其是涉及持久化的时候,真是让人头大。希望这段代码能帮你解决问题。
点赞
2026-02-19 13:12