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

React+Sanity项目Google登录用户头像获取undefined问题排查

问题排查与修复方案

你遇到的头像显示undefined、用户数据获取失败的问题,主要是localStorage处理逻辑错误、useEffect依赖缺失、字段名不匹配、查询参数错误这几个原因导致的,下面逐个修复:


1. 修复localStorage判断逻辑

原代码的判断逻辑存在错误:当localStorage中没有user项时,getItem返回的是null而非字符串'undefined',会错误执行localStorage.clear()(且该方法无返回值,导致userInfo为undefined)。

修复后代码:

const Home = () => {
  const [toggleSidebar, setToggleSidebar] = useState(false);
  const [user, setUser] = useState(null);
  // 优化localStorage读取逻辑
  const storedUser = localStorage.getItem('user');
  const userInfo = storedUser ? JSON.parse(storedUser) : null;
  // 无用户数据时清除本地存储(可选)
  if (!userInfo) localStorage.clear();

  // ...后续代码
}

2. 修复useEffect依赖与查询参数

原useEffect依赖数组为空,且传入userQuery的参数错误:你在Login组件中将Sanity用户文档的_id设为Google返回的userObject.sub,但Home组件传的是userInfo?.googleId,导致查询不到数据;同时依赖缺失会导致userInfo变化时无法重新触发查询。

修复后代码:

useEffect(() => {
  // 无用户数据时直接返回
  if (!userInfo) return;

  // 传入正确的用户标识:userInfo.sub
  const query = userQuery(userInfo.sub);
  client.fetch(query)
    .then((data) => {
      setUser(data[0]);
    })
    .catch(err => console.error('获取用户数据失败:', err)); // 新增错误捕获,方便排查
}, [userInfo]); // 加入userInfo作为依赖,数据变化时重新查询

3. 修复头像字段名不匹配

Login组件中存储到Sanity的头像字段是image,但Home组件渲染时用的是user?.picture,字段名不匹配导致取不到值。

修复后代码:

<Link to={`user-profile/${user?._id}`}>
  {/* 将user?.picture改为user?.image,匹配Sanity存储的字段名 */}
  <img src={user?.image} alt="用户头像" className='w-28'/>
</Link>

4. 额外优化:添加异步加载状态

因为从Sanity获取数据是异步操作,初始时user为null,可以添加加载状态避免显示异常:

const Home = () => {
  const [toggleSidebar, setToggleSidebar] = useState(false);
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true); // 新增加载状态
  const storedUser = localStorage.getItem('user');
  const userInfo = storedUser ? JSON.parse(storedUser) : null;
  if (!userInfo) localStorage.clear();

  useEffect(() => {
    if (!userInfo) {
      setLoading(false);
      return;
    }

    const query = userQuery(userInfo.sub);
    client.fetch(query)
      .then((data) => {
        setUser(data[0]);
        setLoading(false);
      })
      .catch(err => {
        console.error('获取用户数据失败:', err);
        setLoading(false);
      });
  }, [userInfo]);

  return (
    <div className='flex bg-gray-50 md:flex-row flex-col h-screen transaction-height duration-75 ease-out'>
      {/* ...其他代码 */}
      <div className='flex md:hidden flex-row'>
        <HiMenu fontSize={40} className="cursor-pointer" onClick={() => setToggleSidebar(false)} />
        <Link to="/">
          <img src={logo} alt="logo" className="w-28" />
        </Link>
        {/* 根据加载状态渲染不同内容 */}
        {loading ? (
          <div className='w-28 h-28 bg-gray-200 rounded-full'></div>
        ) : user ? (
          <Link to={`user-profile/${user._id}`}>
            <img src={user.image} alt="用户头像" className='w-28'/>
          </Link>
        ) : (
          <div className='text-sm'>未登录</div>
        )}
      </div>
    </div>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 00:55:17