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

React useEffect首次刷新正常,二次刷新后money/luck重置问题求助

问题:刷新两次后money和luck被重置为默认值

首次刷新时代码运行正常,但刷新两次后,money和luck会被重置为默认值1和10。代码逻辑为:通过第一个useEffect获取用户数据并设置状态;第二个useEffect在money或luck变化时将数据推送至API同步到数据库。

用户提供代码:

const [luck, setLuck] = useState(1);
const [money, setMoney] = useState(10);
useEffect(() => {
    const getUser = async () => {
      const res = await fetch(`/api/email/${session?.user?.email}`, {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
          Authorization: "tmthisdumb123",
        },
      });
      const data = await res.json();
      setName(data.name);
      setLuck(data.luck);
      setEmail(data.email);
      setMoney(data.money);
      if (data.rarity && data.quality && data.rarity !== "Unknown") {
        setRarity(data.rarity);
        setQuality(data.quality);
        setLevel(data.level);
        setMold(data.mold);
        setEnchant1(data.enchant1);
        setEnchant2(data.enchant2);
        setEnchant3(data.enchant3);
        setEnchantName1(data.enchantName1);
        setEnchantName2(data.enchantName2);
        setEnchantName3(data.enchantName3);
        setID(data.swordId);
        setValue(
          CalculateRarityValue(data.rarity) *
            CalculateQualityValue(data.quality) *
            CalculateMoldValue(data.mold) *
            (CalculateLevelValue(data.level) * 7.5) *
            CalculateEnchant(data.enchant1) *
            CalculateEnchant(data.enchant2) *
            CalculateEnchant(data.enchant3) *
            EnchantPower(data.enchant1) *
            EnchantPower(data.enchant2) *
            EnchantPower(data.enchant3) *
            CalculateRaritySuffix(data.rarity) *
            20
        );
        setSold(false);
        setGeneratable(true);
      }
      return { user: data };
    };
    getUser();
  }, []);
  // Save the users data everytime luck or money changes
  const saveUser = async () => {
    await fetch(`/api/email/${session?.user?.email}`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: "tmthisdumb123",
      },
      body: JSON.stringify({
        luck: luck,
        money: money,
      }),
    });
  };
  useEffect(() => {
    saveUser();
  }, [money, luck]);

问题原因

组件初始化时,useState先设置luck=1、money=10的默认值,此时第二个useEffect会直接触发saveUser,在第一个useEffect完成真实数据获取前就把默认值同步到了数据库。第一次刷新时,API返回的真实数据会覆盖默认值,所以看起来正常;但第二次刷新时,数据库里已经被默认值覆盖,获取到的就是错误数据,最终显示默认值。

解决方案

1. 增加加载状态,避免初始值触发保存

添加isLoaded状态标记数据是否加载完成,仅在加载完成后执行保存操作:

const [luck, setLuck] = useState(1);
const [money, setMoney] = useState(10);
const [isLoaded, setIsLoaded] = useState(false); // 新增加载状态

useEffect(() => {
    const getUser = async () => {
      const res = await fetch(`/api/email/${session?.user?.email}`, {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
          Authorization: "tmthisdumb123",
        },
      });
      const data = await res.json();
      setName(data.name);
      setLuck(data.luck);
      setEmail(data.email);
      setMoney(data.money);
      // ... 其他状态设置代码
      setIsLoaded(true); // 数据加载完成后标记
    };
    getUser();
  }, []);

const saveUser = async () => {
  if (!isLoaded) return; // 未加载完成时不执行保存
  await fetch(`/api/email/${session?.user?.email}`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: "tmthisdumb123",
    },
    body: JSON.stringify({
      luck: luck,
      money: money,
    }),
  });
};

useEffect(() => {
  saveUser();
}, [money, luck, isLoaded]); // 依赖项添加isLoaded

2. 优化请求触发时机(可选)

如果session在组件挂载时可能未就绪,把session?.user?.email加入第一个useEffect的依赖项,确保用户信息就绪后再发起请求:

useEffect(() => {
  if (!session?.user?.email) return; // 无用户邮箱时不发起请求
  const getUser = async () => {
    // ... 原有请求代码
  };
  getUser();
}, [session?.user?.email]); // 添加session依赖

3. 后端增加校验(可选)

在后端处理保存请求时,校验传入的money/luck是否合理,或者仅支持基于当前数据库数据的增量更新,避免前端错误值直接覆盖真实数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:19:01