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

React useEffect依赖警告、递归循环及资格判断异常问题求助

问题1:useEffect警告与无限循环

原因

  1. 依赖数组包含局部变量showBadge,该变量每次渲染都会重新声明,导致useEffect频繁触发。
  2. 直接将medicationState.EligibilityResponse加入依赖时,redux状态更新会生成新的对象引用,触发useEffect后又dispatch更新状态,形成循环。
  3. 原逻辑未关联当前groupMedItem的唯一标识,无法判断是否已为当前药物获取过资格校验结果。

解决方案

  1. 移除依赖数组中的showBadge,局部变量不应作为useEffect依赖。
  2. 通过groupMedItem.getId()作为唯一标识,在useEffect中判断是否已为当前药物获取过有效响应(需同步调整redux reducer,将响应按id存储)。
  3. 使用useSelector精准获取当前药物对应的资格响应,避免全局状态干扰。

问题2:showBadge始终为true

原因

  1. 所有MedicationBadge组件共用同一个全局的EligibilityResponse,多个组件的请求响应会互相覆盖,导致显示错误结果。
  2. 赋值逻辑错误:仅当isEligible为true时才更新showBadge,若isEligible为false,showBadge保持初始值false,但如果全局状态是其他药物的响应,就会错误显示true。
  3. 未处理响应未返回的情况,可能导致意外的真值判断。

解决方案

  1. 调整redux reducer,将资格校验响应按groupMedItem的id存储(例如eligibilityResponses: { [id: string]: EligibilityResponse })。
  2. 修改showBadge的赋值逻辑,直接根据当前药物的响应结果赋值,默认设为false。
  3. 在useEffect中仅当当前药物未获取过响应时才发起请求。

修改后的代码示例

import React, { useEffect } from 'react';
import { GroupMed } from '../../../../state/ducks/medications/models';
import { medicationsActions } from '../../../../state/ducks/medications';
import { useDispatch, useSelector } from 'react-redux';
import { ApplicationState } from '../../../../state/ducks';
import {
    ChaseJSON,
    ExMedJSON,
    FetchEligibilityRequest,
    PrescriptionJSON,
} from '../../../../state/ducks/medications/types';
import { MedicationStatusProps } from './v2-recipes/medication-status';

export interface MedicationBadgeProps {
    index: number;
    groupMed: GroupMed;
}

const MedicationBadge: React.FC<MedicationStatusProps> = ({ index, groupMed }: MedicationBadgeProps) => {
    const dispatch = useDispatch();
    const groupMedItem = groupMed.groupMedItems[0];
    const itemId = groupMedItem.getId();
    // 精准获取当前药物对应的资格响应
    const eligibilityResponse = useSelector((state: ApplicationState) => 
        state.medicationState.eligibilityResponses?.[itemId]
    );

    // 直接赋值showBadge,默认false
    const showBadge = eligibilityResponse?.data?.isEligible ?? false;

    useEffect(() => {
        // 仅当当前药物未获取过有效响应时发起请求
        if (!eligibilityResponse?.data) {
            const fetchEligibilityRequest: FetchEligibilityRequest = {
                rxcui: groupMedItem.getRxcui(),
                groupMedItemType: groupMedItem.item.groupMedItemType,
                groupMedItemDrug:
                    (groupMedItem.item as ChaseJSON).drug ||
                    (groupMedItem.item as PrescriptionJSON).drug ||
                    (groupMedItem.item as ExMedJSON).externalMed.drug,
                medicationSearchResult:
                    (groupMedItem.item as ChaseJSON).searchResult ||
                    (groupMedItem.item as ExMedJSON).externalMed?.healthProfileMedication?.searchResult,
            };
            dispatch(
                medicationsActions.fetchEligibility(itemId, fetchEligibilityRequest),
            );
        }
    }, [dispatch, itemId, groupMedItem]);

    return showBadge ? (
        <ui-section flowDirection="horizontal" spacingTop="mini">
            <ui-icon imgClass="eligible" spacingRight="mini" style={{ marginLeft: '0px' }}></ui-icon>
        </ui-section>
    ) : <></>;
};

export default MedicationBadge;

补充:redux reducer调整示例

// medications reducer示例
const initialState = {
    // ...其他状态
    eligibilityResponses: {} as Record<string, EligibilityResponse>
};

export default function reducer(state = initialState, action: MedicationsAction) {
    switch (action.type) {
        case 'FETCH_ELIGIBILITY_SUCCESS':
            return {
                ...state,
                eligibilityResponses: {
                    ...state.eligibilityResponses,
                    [action.payload.id]: action.payload.response
                }
            };
        // ...其他case
        default:
            return state;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 14:18:12