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

父组件props状态更新时,如何重渲染React组件并重取Apollo查询?

解决方案

核心问题原因

  • 渲染时直接执行副作用(修改状态、调用refetch)不符合React执行逻辑,会导致渲染异常
  • Apollo默认缓存策略优先读取旧缓存,登录后请求默认复用了之前未登录时的缓存结果
  • 之前useEffect无限循环大概率是依赖数组包含了会在effect执行时变化的变量,而非稳定引用的变量

修复后的完整代码

import React, { useEffect } from 'react';
import { useQuery } from "@apollo/client";

import { ME } from "../../api/authentication/me";
import LogoutButton from "../authentication/authentication-required/logout-button";

const Nav = ({ userIsAuthenticated }) => {
  const { data, loading, error, refetch } = useQuery(ME, {
    // 未登录时跳过查询,避免生成无效缓存
    skip: !userIsAuthenticated,
    // 强制请求后端接口,不走本地旧缓存
    fetchPolicy: "network-only"
  });

  // 仅在登录状态变为true时触发重查,不会产生无限循环
  useEffect(() => {
    if (userIsAuthenticated) {
      refetch();
    }
  }, [userIsAuthenticated, refetch]);

  if (loading) return "User is loading...";
  if (error) console.log(error);

  return (
    <div className="Nav">
      <br />
      { JSON.stringify(data, null, 2) }
      <br />
      <LogoutButton/>
    </div>
  )
}

关键修改说明

  1. 新增skip: !userIsAuthenticated配置:未登录时不执行ME查询,避免产生无效缓存,也减少无用请求
  2. 新增fetchPolicy: "network-only"配置:强制每次查询都请求后端接口,不走本地缓存,确保拿到最新的登录用户数据
  3. 用useEffect监听userIsAuthenticated变化:只有登录状态切换为true时才触发refetch,依赖数组仅放入稳定引用的userIsAuthenticated和refetch,不会产生无限循环
  4. 移除了渲染流程中的状态修改和冗余的setTimeout逻辑,符合React执行规范
  5. 修正了原代码中useQuery返回值的错误拼写:原errors应为error

额外排查点

如果修改后仍不生效,请检查Apollo客户端的请求拦截器配置,确认用户登录成功后,后续的ME请求已经携带了正确的身份凭证(token),如果请求头未携带登录凭证,接口仍会返回未登录状态的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 13:39:04