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

React中如何使用useContext将Fullcalendar数据同步存储到localStorage?

问题原因及解决方案

第一个问题(第一条数据存不上)的根源

React的setState是异步更新的,你在调用setState后立刻读取state.externalEvents,拿到的还是更新前的旧值,所以第一次新增时存到localStorage的是空数组,第二次新增时才会存入第一次的内容,看起来就像第一条没保存。

第二个问题(接入Context后功能失效)的常见原因

  1. App组件缺少return语句:你贴的App组件代码里只写了JSX,没有return包裹,导致Provider根本没有渲染,子组件拿不到Context值。
  2. 数据结构不匹配:你之前在Todo组件里单独存的是state.externalEvents数组,但是DataProvider里的todos是{externalEvents: []}的对象结构,初始化时直接把数组赋值给todos,会导致后续读取state.externalEvents为undefined,渲染列表时报错。
  3. 重复的localStorage写入逻辑:Todo组件里的手动写localStorage代码和Provider里的自动写逻辑冲突,且因为异步问题存的是旧值。

具体修改步骤

步骤1:修正App组件的返回逻辑

给App组件加上return,确保Provider正常包裹所有子组件:

import React from "react";
import {DataProvider} from './components/calendar/DataProvider'
// 其他导入...
function App() {
  return (
    <DataProvider>
      {/* 你的其他布局代码 */}
      <Switch>
        {/* 其他路由 */}
        <Route path="/calendar" component={Calendar} />
      </Switch>
    </DataProvider>
  )
}
export default App;

步骤2:优化DataProvider的初始化逻辑,兼容旧数据

修改DataProvider里的初始化useEffect,处理之前存的数组格式旧数据,避免结构不匹配:

import React,{useState,useEffect,createContext} from 'react'
export const DataContext = createContext();
export const DataProvider = (props) => {
    const [todos, setTodos] = useState({
      externalEvents: [],
    });
    useEffect(() => {
      const todoStore = JSON.parse(localStorage.getItem('todoStore'))
      if(todoStore) {
        // 兼容旧版数组格式的存储数据
        if(Array.isArray(todoStore)) {
          setTodos({ externalEvents: todoStore })
        } else {
          setTodos(todoStore)
        }
      }
    },[])
    useEffect(() => {
      localStorage.setItem('todoStore', JSON.stringify(todos));
    },[todos])
  return (
   <DataContext.Provider value={[todos,setTodos]}>
     {props.children}
   </DataContext.Provider>
  )
}

步骤3:替换Calendar组件的本地状态为Context全局状态

在Calendar组件中导入DataContext,替换原来的本地useState:

import { useContext } from 'react'
import { DataContext } from './DataProvider'
// 其他导入...
export default function Calendar() {
  // 替换原来的const [state, setState] = useState({externalEvents: []})
  const [state, setState] = useContext(DataContext)
  // 剩下的原有代码不变,继续把state和setState传给Todo组件即可
}

步骤4:删除Todo组件里冗余的localStorage代码

删掉Todo组件addTodo函数里的手动存localStorage的那行,现在Provider会自动处理持久化,避免异步导致的存旧值问题:

const addTodo = (e) => {
  e.preventDefault();
  if (title === "" || color === "") {
    alert("please type what to do or choose a color");
  } else {
    setState({
      externalEvents: [
        ...state.externalEvents,
        { title: title, color: color, custom: custom, id: uuidv4(), },
      ],
    });
    // 删掉下面这行!!!
    // localStorage.setItem("todoStore", JSON.stringify(state.externalEvents));
    setTitle("");
    setCustom("");
  }
};

验证效果

修改完成后:

  1. 新增第一条数据就会自动同步到localStorage,不会再出现丢失的情况
  2. 刷新页面后,Provider会自动从localStorage读取数据,事件列表不会丢失
  3. 所有子组件都可以通过useContext拿到最新的事件列表,实现全局状态共享

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:15:03