You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+TypeScript+Redux Toolkit操作localStorage增删收藏国家出错

问题分析与修复方案

先梳理你代码里的几个核心问题:

  1. 无重复添加限制:addToFavourite里直接执行push操作,没判断当前国家是否已在收藏列表,会导致同一个国家被多次加入。
  2. 收藏数量不同步:removeFavourite只更新了收藏数组,没同步减少postNumber,导致数字和实际收藏数量对不上。
  3. 冗余代码:删除逻辑里const removeItem = (state.post = state.post.filter(...)); state.post = removeItem;完全多余,直接赋值给state.post即可。
  4. 无localStorage错误处理:直接用JSON.parse读取存储内容,若内容格式损坏会直接抛出错误导致页面崩溃。

修复后的完整代码

import { createSlice } from "@reduxjs/toolkit";
import type { PayloadAction } from "@reduxjs/toolkit";

type Country = {
  flags: {
    svg: string;
  };
  name: {
    common: string;
  };
  region: string;
  capital: string[];
  population: number;
};

interface InitialState {
  post: Country[];
  postNumber: number;
}

// 封装localStorage读取逻辑,增加异常捕获
const loadFromLocalStorage = <T>(key: string, defaultValue: T): T => {
  try {
    const item = localStorage.getItem(key);
    return item ? JSON.parse(item) : defaultValue;
  } catch (error) {
    console.error(`读取localStorage键${key}失败`, error);
    return defaultValue;
  }
};

const initialState: InitialState = {
  post: loadFromLocalStorage("postItem", []),
  postNumber: loadFromLocalStorage("postNumber", 0),
};

// 封装localStorage保存逻辑,增加异常捕获
const saveToLocalStorage = (key: string, value: any) => {
  try {
    localStorage.setItem(key, JSON.stringify(value));
  } catch (error) {
    console.error(`保存localStorage键${key}失败`, error);
  }
};

export const postSlice = createSlice({
  name: "Post",
  initialState,
  reducers: {
    addToFavourite: (state, action: PayloadAction<Country>) => {
      // 先判断当前国家是否已在收藏列表中
      const isAlreadyAdded = state.post.some(
        (post) => post.name.common === action.payload.name.common
      );
      if (!isAlreadyAdded) {
        state.post.push(action.payload);
        state.postNumber += 1;
        saveToLocalStorage("postItem", state.post);
        saveToLocalStorage("postNumber", state.postNumber);
      }
    },

    removeFavourite: (state, action: PayloadAction<string>) => {
      const postName = action.payload;
      state.post = state.post.filter(
        (post) => post.name.common !== postName
      );
      // 直接用数组长度同步收藏数量,避免手动计算出错
      state.postNumber = state.post.length;
      saveToLocalStorage("postItem", state.post);
      saveToLocalStorage("postNumber", state.postNumber);
    },
  },
});

export const { addToFavourite, removeFavourite } = postSlice.actions;

export default postSlice.reducer;

关键修复点说明

  • 拦截重复添加:用some方法检查当前国家是否已存在,仅当不存在时执行添加逻辑。
  • 同步收藏数量:删除后直接将postNumber设为数组长度,避免手动增减导致的计数错误。
  • 异常处理:封装读写localStorage的函数,捕获JSON解析或存储时的异常,防止页面崩溃。
  • 简化代码逻辑:移除冗余的变量赋值,让增删逻辑更简洁清晰。

内容的提问来源于stack exchange,提问作者clemon ezeh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 13:20:15