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

React Context中页面刷新后LocalStorage无法保留数据问题

问题修复:React Context 同步LocalStorage刷新后丢失数据

核心错误分析

  1. useState 初始化方式错误
    你把初始化函数放在了useState的第二个参数位置,这是不对的。useState如果需要函数式初始化(比如从LocalStorage读值),应该把这个函数直接作为第一个参数传入,否则初始值永远是空数组[],刷新后自然读不到LocalStorage里的数据。

  2. updatePokemons 中删除操作无效
    slice()方法不会修改原数组,只会返回截取后的新数组,所以你执行updatedPokemons.slice(pokemonsIndex, 1)后,updatedPokemons本身根本没变化,删除操作等于没执行。

  3. deletePokemon 函数的多处错误

    • 直接修改state数组pokemons.splice(...)违反React的不可变原则,必须通过setPokemons更新状态;
    • splice的参数不正确,删除单个元素需要传index, 1,只传index会删除从该位置到数组末尾的所有元素;
    • 没必要加async/await,splice是同步操作,没有异步逻辑;
    • toString(name)多余,若传入的name已经是字符串,这步完全没必要,若不是应该提前处理类型。

修复后的完整代码

import React, { useEffect, useState } from "react";
import CatchContext from "./Context";

const CatchProvider = ({ children }) => {
    // 修复:用函数式初始化作为useState的第一个参数
    const [pokemons, setPokemons] = useState(() => {
        const dataStorage = localStorage.getItem('pokemons');
        return dataStorage ? JSON.parse(dataStorage) : [];
    });
    
    useEffect(() => {
        localStorage.setItem('pokemons', JSON.stringify(pokemons));
    }, [pokemons]);

    const updatePokemons = (name) => {  
        const pokemonsIndex = pokemons.indexOf(name);
        if (pokemonsIndex >= 0) { 
            // 修复:用filter创建新数组(更符合不可变原则),替代slice
            setPokemons(prev => prev.filter(p => p !== name));
        } else { 
            // 用函数式更新,避免依赖外部state的快照
            setPokemons(prev => [...prev, name]);
        }
    }     
  
    const deletePokemon = (name) => {   
        // 修复:用filter创建新数组,通过setPokemons更新
        setPokemons(prev => prev.filter(p => p !== name));
    }  

    return (
        <CatchContext.Provider value={{ pokemons, updatePokemons, deletePokemon }}>
            {children}
        </CatchContext.Provider>
    );
}

export default CatchProvider;  

额外优化点

  • 在updatePokemons和deletePokemon中使用函数式更新(setPokemons(prev => ...)),可以避免因为闭包问题导致的state快照过期,确保每次更新都基于最新的state值。
  • 用filter替代splice来删除元素,更符合React的不可变数据原则,代码也更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:05:33