React开发:如何让ArgoCD应用状态每个组件仅显示一次
问题:ArgoCD应用同步状态重复显示两次
我有一个用于展示状态的ShowApplication组件,当前通过遍历applications数组渲染ArgoCD应用的同步状态,但每个组件的'Synced'状态被重复显示了两次。需要实现每个组件对应的状态仅显示一次。
组件代码
import React, { useEffect } from 'react'; import { useEntity } from '@backstage/plugin-catalog-react'; import { isArgoCDAvailable } from './utils/isArgoCDAvailable'; import { configApiRef, useApi } from '@backstage/core-plugin-api'; import { AppData } from './utils/types'; function ShowApplication({ appName, applications, setApplications, factory, namespaces, }: Props) { const getApplication = async () => { if (isArgoCDAvailable(entity)) { const response = await fetch( `${backendUrl}/api/sisalArgoCD/argoCD/application/${factory}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(namespaces), }, ); const payload = await response.json(); setApplications(payload.applications); } }; return ( <div> {applications.map((application: AppData) => { return <p>{application.status.sync.status}</p>; })} </div> ); } export default ShowApplication;
父组件渲染代码
elements.push( <div style={{ margin: '10px 0px' }}> {/* use argocd-accordion class to style accordion */} <Accordion classes={{ root: 'argocd-accordion' }}> <AccordionSummary expandIcon={<ExpandMoreIcon />} aria-controls={`panel${key}-content`} id={`panel${key}-header`} > <ShowApplication appName={ key === 'dataProd' ? 'Dataplatform Prod' : 'Dataplatform Preprod' } applications={applications} setApplications={setApplications} factory={factory} namespaces={namespaces} /> </AccordionSummary> {deploymentsRow} {items} </Accordion> </div>, );
解决方案
1. 给遍历元素添加唯一key
React渲染列表时需要唯一key来区分元素,避免因DOM复用导致的重复渲染。修改ShowApplication的返回部分:
return ( <div> {applications.map((application: AppData) => { // 假设每个application有唯一的name字段,用它作为key,可根据实际唯一标识调整 return <p key={application.name}>{application.status.sync.status}</p>; })} </div> );
2. 对applications数组去重
如果后端返回的数组本身存在重复条目,在设置状态前先去重。修改getApplication中的状态更新逻辑:
const payload = await response.json(); // 按应用唯一标识去重,这里用name作为唯一键,可替换为实际唯一字段(如uid) const uniqueApps = [...new Map(payload.applications.map(app => [app.name, app])).values()]; setApplications(uniqueApps);
3. 修复useEffect的缺失与依赖问题
原组件未通过useEffect触发数据获取,且缺少必要变量声明,补充完整逻辑避免重复请求:
function ShowApplication({ appName, applications, setApplications, factory, namespaces, }: Props) { // 补充缺失的变量声明 const { entity } = useEntity(); const configApi = useApi(configApiRef); const backendUrl = configApi.getString('backend.baseUrl'); const getApplication = async () => { if (isArgoCDAvailable(entity)) { const response = await fetch( `${backendUrl}/api/sisalArgoCD/argoCD/application/${factory}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(namespaces), }, ); const payload = await response.json(); const uniqueApps = [...new Map(payload.applications.map(app => [app.name, app])).values()]; setApplications(uniqueApps); } }; // 添加useEffect,仅在依赖变化时触发数据获取 useEffect(() => { getApplication(); }, [entity, factory, namespaces]); // 依赖项根据业务调整,避免不必要的重复请求 return ( <div> {applications.map((application: AppData) => { return <p key={application.name}>{application.status.sync.status}</p>; })} </div> ); }
4. 检查父组件渲染逻辑
确认父组件中elements.push的执行逻辑,避免因循环条件错误导致同一个ShowApplication被多次添加。比如检查循环的key是否唯一,是否存在重复触发push的情况。
内容的提问来源于stack exchange,提问作者Stiven Ballshi
相关产品推荐
相关产品推荐

