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

React中LocalStorage与useState页面刷新竞态问题修复咨询

修复购物车LocalStorage存储的竞态问题

问题根源

你的代码中,cartItems初始化为空数组[],会触发依赖它的useEffect将LocalStorage清空;而加载LocalStorage数据的useEffect是异步执行的,导致旧数据还没加载完成就被初始空数组覆盖,出现竞态条件。

修复方案

方案一:函数式初始化State(推荐)

利用React的函数式初始State,直接从LocalStorage读取初始值,同时避免服务器端渲染时window未定义的报错:

"use client";
import React, { useState, useEffect } from "react";

export default function Home() {
  // 函数式初始值,仅在组件首次渲染时执行
  const [cartItems, setCartItems] = useState(() => {
    // 先判断window是否存在,避免SSR报错
    if (typeof window !== "undefined") {
      const savedCart = localStorage.getItem("cartItems");
      return savedCart ? JSON.parse(savedCart) : [];
    }
    return [];
  });

  // 仅在cartItems变化时存储到LocalStorage
  useEffect(() => {
    console.log("storing cart items", JSON.stringify(cartItems));
    localStorage.setItem("cartItems", JSON.stringify(cartItems));
  }, [cartItems]);

  return <div>{JSON.stringify(cartItems)}</div>;
}

这种方式直接跳过了初始空数组触发存储的步骤,从根源上解决竞态问题,同时兼容服务器端渲染场景。

方案二:用useRef标记初始化状态

如果不想修改初始State的方式,可以通过useRef标记组件是否完成初始化,避免初始空数组触发存储:

"use client";
import React, { useState, useEffect, useRef } from "react";

export default function Home() {
  const [cartItems, setCartItems] = useState([]);
  // 标记是否完成LocalStorage数据加载
  const isInitialized = useRef(false);

  useEffect(() => {
    const cartItemsData = JSON.parse(localStorage.getItem("cartItems"));
    if (cartItemsData) {
      console.log("loaded cart items data", cartItemsData);
      setCartItems(cartItemsData);
    }
    // 加载完成后标记初始化完成
    isInitialized.current = true;
  }, []);

  useEffect(() => {
    // 仅初始化完成后才执行存储操作
    if (isInitialized.current) {
      console.log("storing cart items", JSON.stringify(cartItems));
      localStorage.setItem("cartItems", JSON.stringify(cartItems));
    }
  }, [cartItems]);

  return <div>{JSON.stringify(cartItems)}</div>;
}

关于空字符串初始值能工作的原因

当初始值设为空字符串时,首次触发存储的是"",后续加载LocalStorage时JSON.parse("")会返回null,不会覆盖购物车数据;但这种方式属于临时规避,不规范且可能引发其他问题,建议使用上面的标准方案修复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 12:12:38