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

在React Amplify中使用AWS Cognito自定义属性作为查询过滤器遇问题

解决方案:从Cognito获取自定义属性并用于Amplify Data查询过滤

问题根源分析

  1. 初始默认值干扰:你设置的默认值"999999999"会在异步获取属性完成前显示,导致短暂的错误状态。
  2. 异步操作未处理错误:fetchUserAttributes可能返回的属性中没有custom:customer_id,或者调用失败,直接返回undefined。
  3. useEffect依赖缺失:第一个useEffect没有依赖数组,会在组件每次渲染时重复执行,可能导致状态混乱。
  4. 查询未做条件判断:当companyId为undefined时,依然执行查询,可能引发无效请求。

具体修复步骤

1. 完善用户属性获取函数,添加错误处理与日志

确保能捕获异常,并确认自定义属性是否存在:

const getUserAttributes = async () => {
  try {
    const userAttributes = await fetchUserAttributes();
    // 打印属性确认是否包含custom:customer_id
    console.log('用户属性:', userAttributes);
    const customerId = userAttributes['custom:customer_id'];
    if (!customerId) {
      throw new Error('用户属性中未找到custom:customer_id');
    }
    return customerId.toString();
  } catch (err) {
    console.error('获取用户属性失败:', err);
    return null;
  }
};

2. 调整组件状态与useEffect逻辑

  • 移除误导性的默认值,改用null作为初始状态
  • 添加加载状态,避免初始值显示
  • 确保获取属性的useEffect仅执行一次
  • 仅当companyId有效时才执行查询,并清理订阅避免内存泄漏

修改后的组件代码:

import { useEffect, useState } from "react";
import type { Schema } from "../amplify/data/resource";
import { generateClient } from "aws-amplify/data";
import { Authenticator } from '@aws-amplify/ui-react'
import '@aws-amplify/ui-react/styles.css'

import Container from 'react-bootstrap/Container';
import { fetchUserAttributes } from 'aws-amplify/auth';
import AccountSummary from "./AccountSummary";
import CustomerRecommendations from "./CustomerRecommendations";
const client = generateClient<Schema>();

const getUserAttributes = async () => {
  try {
    const userAttributes = await fetchUserAttributes();
    console.log('用户属性:', userAttributes);
    const customerId = userAttributes['custom:customer_id'];
    if (!customerId) {
      throw new Error('用户属性中未找到custom:customer_id');
    }
    return customerId.toString();
  } catch (err) {
    console.error('获取用户属性失败:', err);
    return null;
  }
};

function App() {
  const [summaries, setSummaries] = useState<Array<Schema["CustomerSummary"]["type"]>>([]);
  const [recommendations, setRecommendations] = useState<Array<Schema["CustomerRecommendation"]["type"]>>([]);
  const [companyId, setCompanyId] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  // 仅在组件挂载时获取一次用户属性
  useEffect(() => {
    const loadCompanyId = async () => {
      const customerId = await getUserAttributes();
      setCompanyId(customerId);
      setIsLoading(false);
    };
    loadCompanyId();
  }, []);

  // 查询CustomerSummary,仅当companyId有效时执行
  useEffect(() => {
    if (!companyId) return;

    const subscription = client.models.CustomerSummary.observeQuery({
      filter: {
        customer_id: {        
          eq: companyId
        }
      }
    }).subscribe({
      next: (data) => setSummaries([...data.items]),
      error: (err) => console.error('获取汇总数据失败:', err)
    });

    // 组件卸载时清理订阅
    return () => subscription.unsubscribe();
  }, [companyId]);

  // 查询CustomerRecommendations,仅当companyId有效时执行
  useEffect(() => {
    if (!companyId) return;

    const subscription = client.models.CustomerRecommendation.observeQuery({
      filter: {
        customer_id: {
          eq: companyId
        }
      }
    }).subscribe({
      next: (data) => setRecommendations([...data.items]),
      error: (err) => console.error('获取推荐数据失败:', err)
    });

    return () => subscription.unsubscribe();
  }, [companyId]);

  // 加载中状态
  if (isLoading) {
    return <div>加载中...</div>;
  }

  // 未获取到有效companyId时显示错误
  if (!companyId) {
    return <div>无法获取客户ID,请检查认证状态。</div>;
  }

  return (
    <Authenticator>
      <Container>
        <AccountSummary summaries={summaries} />
        <CustomerRecommendations recommendations={recommendations} />
      </Container>
    </Authenticator>
  );
}

export default App;

额外注意事项

  • 确认Cognito用户池已正确配置custom:customer_id自定义属性,并且在用户注册/更新时已赋值。
  • 检查Cognito应用客户端是否有读取自定义属性的权限(在用户池应用客户端设置中,确保custom:customer_id在允许的属性列表里)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 14:40:11