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

Supabase实时事件异常:两处信用值仅一处更新

解决两处信用数值组件不同步更新的问题

问题重现

页面中两处复用CreditsNummer组件展示用户信用值,用户兑换1个信用后,仅其中一处数值更新,另一处始终保持原值。

核心原因

  1. 局部状态隔离:每个CreditsNummer组件实例都维护独立的userCredits局部状态,实时订阅触发的setUserCredits只会更新当前组件的状态,其他组件实例无法感知该变化。
  2. 全局状态未同步:兑换操作后,useUser钩子中的userDetails没有同步更新,导致未触发更新的组件仍使用旧的初始值计算信用。

解决方案(推荐方案)

移除组件内部的局部状态,直接基于全局的userDetails计算信用值,同时修复实时订阅逻辑,确保全局状态同步更新:

import { useUser } from "@/hooks/useUser";
import { createClientComponentClient } from "@supabase/auth-helpers-nextjs";
import React, { useEffect } from "react";

const CreditsNummer = () => {
  const { user, userDetails, isLoading } = useUser();
  const supabase = createClientComponentClient();

  // 直接从全局userDetails计算总信用,无需维护局部状态
  const userCredits = userDetails 
    ? userDetails.credits_pay_per_removal + userDetails.credits_subscription 
    : 0;

  useEffect(() => {
    if (!user) return;

    const channel = supabase
      .channel(`realtime-credits-${user.id}`)
      .on(
        "postgres_changes",
        {
          event: "*",
          schema: "public",
          table: "users",
          // 只监听当前用户的信用变更,减少无效触发
          filter: `id=eq.${user.id}`
        },
        async (payload) => {
          if (payload.new && "credits_pay_per_removal" in payload.new && "credits_subscription" in payload.new) {
            // 重新拉取用户详情,同步更新全局userDetails
            const { data } = await supabase
              .from("users")
              .select("credits_pay_per_removal, credits_subscription")
              .eq("id", user.id)
              .single();
            
            // 假设useUser钩子提供了更新userDetails的方法,比如updateUserDetails
            // 如果没有,需要在useUser内部添加状态更新逻辑,确保全局同步
            // updateUserDetails(data);
          }
        }
      )
      .subscribe();

    return () => {
      supabase.removeChannel(channel);
    };
  }, [supabase, user]);

  if (isLoading) {
    return <p>Loading...</p>;
  }

  return <div>{user ? userCredits : 0}</div>;
};

export default CreditsNummer;

关键修改说明

  1. 移除局部状态:直接通过userDetails计算信用值,确保所有组件实例使用同一数据源,全局更新时自动同步。
  2. 精准订阅过滤:添加用户ID过滤条件,只监听当前用户的信用变更,避免无关数据触发更新。
  3. 同步全局状态:实时订阅触发后,重新拉取用户详情并更新全局的userDetails,确保所有依赖该状态的组件都能感知变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:52:38