Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop

Hiba Youssef

enter image description here

I have a project, and this project contains several interfaces, and among these interfaces there is an interface in order to display the medical plan shown in the image, and as shown in the image, the medical plan contains several sections, and the appearance of these sections differs from one role to another,

When I log in with a specific role account, let it be “Cobalt”, since Cobalt is not allowed to see the rest of the sections, it is only allowed to see the Cobalt section, and in order not to call the api for the other sections, I used:

useState
enabled
setState

But I got this error,

Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

How can I solve the problem?

import { Col, Collapse, Row, Tag } from 'antd';
import {
    FunctionComponent, useContext, useMemo, useState,
} from 'react';
import { FormattedMessage } from 'react-intl';
import { useQueries } from 'react-query';
import { useParams } from 'react-router';
import analysis from '../../../../../api/nuclearMedicineApi/services/Analysis';
import examination from '../../../../../api/nuclearMedicineApi/services/Examination';
import radialImage from '../../../../../api/nuclearMedicineApi/services/RadialImageByXRay';
import radialImageByMRI from '../../../../../api/nuclearMedicineApi/services/RadialImageByMRI'
import radioTherapyByCesium from '../../../../../api/nuclearMedicineApi/services/RadioTherapyByCesium';
import radioTherapyByCobalt from '../../../../../api/nuclearMedicineApi/services/RadioTherapyByCobalt';
import radioTherapyByIodine from '../../../../../api/nuclearMedicineApi/services/RadioTherapyByIodine';
import radioTherapyByLinac from '../../../../../api/nuclearMedicineApi/services/RadioTherapyByLinac';
import { IFormProps } from '../../../../../interfaces/form-props';
import FormElement from '../../../../common/form-element';
import AnalysisPage from '../../Analysis';
import ExaminationPage from '../../Examination';
import RadioTherapyByCesiumPage from '../../radio-therapy-by-cesium';
import RadioTherapyByCobaltPage from '../../radio-therapy-by-cobalt';
import RadioTherapyByLinacPage from '../../radio-therapy-by-linac';
import RadioTherapyByIodinePage from '../../radio-therapy-by-lodine';
import { Divider } from 'antd';
import RadialImageByCTPage from '../../radial-image-by-ct';
import RadialImageByGammaPage from '../../radial-image-by-gamma';
import RadialImageByMRIPage from '../../radial-image-by-mri';
import RadialImageByXRAYPage from '../../radial-image-by-xray';
import radialImageByCT from '../../../../../api/nuclearMedicineApi/services/RadialImageByCT';
import radialImageByGamma from '../../../../../api/nuclearMedicineApi/services/RadialImageByGamma';
import { AuthContext } from '../../../../../contexts/auth-context';
import { panelPlan } from '../../../../../constants/enums';

interface PlanFormProps extends IFormProps { }

const PlanForm: FunctionComponent<PlanFormProps> = ({
    control,
    disabled,
    type,
    data,
}) => {

    const authContext = useContext(AuthContext);
    const role = authContext?.userData?.roleNames?.[0];

    const userRoles = authContext?.userData?.roleNames;
    const sharedProps = {
        control,
        disabled,
    };

    const { caseId, planId } = useParams();

    const [analysisCalled, setAnalysisCalled] = useState(false); 
    const [ct, setCt] = useState(false); 
    const [gamma, setGamma]= useState(false); 
    const [mri, setMri] = useState(false); 
    const [xray, setXray] = useState(false); 
    const [cesium, setCesium] = useState(false); 
    const [cobalt, setCobalt] = useState(false); 
    const [linac, setLinac] = useState(false); 
    const [iodin, setIodin] = useState(false); 
    const [examinationCalled, setExaminationCalled] = useState(false); 


    const { Panel } = Collapse;

    const results = useQueries([
        {
            queryKey: ['examination', caseId, planId],
            enabled: !! examinationCalled, 
            queryFn: () =>
                examination
                    .examinationGetAll({
                        CaseId: +caseId!,
                        PlanId: +planId!,
                    })
                    .then((data) => data.totalCount),
        },
        {
            queryKey: ['analysis', caseId, planId],
            enabled: !! analysisCalled, 
            queryFn: () =>
                analysis
                    .analysisGetAll({
                        CaseId: +caseId!,
                        PlanId: +planId!,
                    })
                    .then((data) => data.totalCount),
        },
        // ***************************************
        {
            queryKey: ['RadialImageByCT', caseId, planId],
            enabled: !! ct, 
            queryFn: () =>
                radialImageByCT
                    .RadialImageByCTGetAll({
                        CaseId: +caseId!,
                        PlanId: +planId!,
                    })
                    .then((data) => data.totalCount),
        },

        {
            queryKey: ['RadialImageByMRI', caseId, planId],
            enabled: !! mri, 
            queryFn: () =>
                radialImageByMRI
                    .radialImageByMRIGetAll({
                        CaseId: +caseId!,
                        PlanId: +planId!,
                    })
                    .then((data) => data.totalCount),
        },

        {
            queryKey: ['RadialImageByGamma', caseId, planId],
            enabled: !!gamma, 
            queryFn: () =>
                radialImageByGamma
                    .RadialImageByGammaGetAll({
                        CaseId: +caseId!,
                        PlanId: +planId!,
                    })
                    .then((data) => data.totalCount),
        },
        {
            queryKey: ['RadialImageByXRay', caseId, planId],
            enabled: !! xray, 
            queryFn: () =>
                radialImage
                    .radialImageGetAll({
                        CaseId: +caseId!,
                        PlanId: +planId!,
                    })
                    .then((data) => data.totalCount),
        },
        // ****************************
        {

            queryKey: ['radioTherapyByCesium', caseId, planId],
            enabled: !! cesium, 
            queryFn: () =>
                radioTherapyByCesium
                    .RadioTherapyByCesiumGetAll({
                        CaseId: +caseId!,
                        PlanId: +planId!,
                    })
                    .then((data) => data.totalCount),
        },
        {
            queryKey: ['radioTherapyByCobalt', caseId, planId],
            enabled: !! cobalt, 
            queryFn: () =>
                radioTherapyByCobalt
                    .RadioTherapyByCobaltGetAll({
                        CaseId: +caseId!,
                        PlanId: +planId!,
                    })
                    .then((data) => data.totalCount),
        },
        {
            queryKey: ['radioTherapyByLinac', caseId, planId],
            enabled: !! linac, 
            queryFn: () =>
                radioTherapyByLinac
                    .RadioTherapyByLinacGetAll({
                        CaseId: +caseId!,
                        PlanId: +planId!,
                    })
                    .then((data) => data.totalCount),
        },
        {
            queryKey: ['radioTherapyByIodine', caseId, planId],
            enabled: !! iodin, 
            queryFn: () =>
                radioTherapyByIodine
                    .RadioTherapyByIodineGetAll({
                        CaseId: +caseId!,
                        PlanId: +planId!,
                    })
                    .then((data) => data.totalCount),
        },
    ]);

    let libMax = 0;
    libMax = Math.max(...results.slice(6, 11).map((item, index) => +item.data!))
    if (libMax === 0)
        libMax = Math.max(...results.slice(2, 6).map((item, index) => +item.data!))
    // console.log("max count : " + libMax);

    let indexQueryMaxCount = 0;

    results?.map((row: any, index: number) => {
        if (row?.data === libMax)
            indexQueryMaxCount = index;
    });

    const genExtra = (queryKey: number) => (
        <Tag>{results[queryKey].data}</Tag>
    );

    return (
        <Row gutter={3}>
            <Col className='mb-8' span={12}>
                <FormElement
                    {...sharedProps}
                    type='input'
                    label='name'
                    name='name'
                    disabled
                />
            </Col>

            {(type === 'Details' || type === 'Update') && panelPlan.map((tab) => {
                const userAllowed = tab.allowedRoles.some(e => userRoles?.includes(e));
                if (tab.name == 'Analysiss' && userAllowed) {
                    setAnalysisCalled(true);
                    return (
                        <Col span={24} >
                            <Collapse accordion defaultActiveKey={indexQueryMaxCount}>
                                <Panel
                                    header={<FormattedMessage id='analysiss' />}
                                    key='1'
                                    extra={genExtra(1)}
                                    style={{ backgroundColor: '#ffc90e' }}
                                >
                                    <AnalysisPage
                                        caseId={Number(caseId)}
                                        planId={data?.id}
                                    />
                                </Panel>
                            </Collapse>
                        </Col>
                    )
                }
            })}



            {/* *********************************** */}
            {/* {
                (isCt === true || isGamma === true || isMRIRadiologist === true || isXRayRadiologist === true) && */}
                <Divider style={{ marginTop: '10px', marginBottom: '10px' }} />
            {/* } */}
            {(type === 'Details' || type === 'Update') && (
                <Col span={24}>
                    <Collapse accordion defaultActiveKey={indexQueryMaxCount}>

                        {panelPlan.map((tab) => {
                            const userAllowed = tab.allowedRoles.some(e => userRoles?.includes(e));
                            if (tab.name == 'RadialImageByCT' && userAllowed) {
                                setCt(true); 
                                return (
                                    <Panel
                                        header={<FormattedMessage id='RadialImageByCTs' />}
                                        key='2'
                                        extra={genExtra(2)}
                                        style={{ backgroundColor: '#c8bfe7' }}
                                    >
                                        <RadialImageByCTPage
                                            caseId={Number(caseId)}
                                            planId={data?.id}
                                        />
                                    </Panel>
                                )
                            }
                        })}
                        {panelPlan.map((tab) => {
                            const userAllowed = tab.allowedRoles.some(e => userRoles?.includes(e));
                            if (tab.name == 'RadialImageByMRI' && userAllowed) {
                                setMri(true); 
                                return (<Panel
                                    header={<FormattedMessage id='RadialImageByMRIs' />}
                                    key='3'
                                    extra={genExtra(3)}
                                    style={{ backgroundColor: '#c8bfe7' }}
                                >
                                    <RadialImageByMRIPage
                                        caseId={Number(caseId)}
                                        planId={data?.id}
                                    />
                                </Panel>
                                )
                            }
                        })}

                        {panelPlan.map((tab) => {
                            const userAllowed = tab.allowedRoles.some(e => userRoles?.includes(e));
                            if (tab.name == 'RadialImageByGamma' && userAllowed) {
                                setGamma(true); 
                                return (
                                    <Panel
                                        header={<FormattedMessage id='RadialImageByGamma' />}
                                        key='4'
                                        extra={genExtra(4)}
                                        style={{ backgroundColor: '#c8bfe7' }}
                                    >
                                        <RadialImageByGammaPage
                                            caseId={Number(caseId)}
                                            planId={data?.id}
                                        />
                                    </Panel>
                                )
                            }
                        })}
                        {panelPlan.map((tab) => {
                            const userAllowed = tab.allowedRoles.some(e => userRoles?.includes(e));
                            if (tab.name == 'RadialImageByXRay' && userAllowed) {
                                setXray(true); 
                                return (
                                    <Panel
                                        header={<FormattedMessage id='RadialImageByXRays' />}
                                        key='5'
                                        extra={genExtra(5)}
                                        style={{ backgroundColor: '#c8bfe7' }}
                                    >
                                        <RadialImageByXRAYPage
                                            caseId={Number(caseId)}
                                            planId={data?.id}
                                        />
                                    </Panel>
                                )
                            }
                        })}

                        {/* ********************* */}


                    </Collapse>
                </Col>
            )}



            <Divider style={{ marginTop: '10px', marginBottom: '10px' }} />

            {(type === 'Details' || type === 'Update') && (

                <Col span={24}>
                    <Collapse accordion defaultActiveKey={indexQueryMaxCount}>
                        {panelPlan.map((tab) => {
                            const userAllowed = tab.allowedRoles.some(e => userRoles?.includes(e));
                            if (tab.name == 'RadioTherapyByCesium' && userAllowed) {
                                setCesium(true); 
                                return (
                                    <Panel
                                        header={
                                            <FormattedMessage id='CesiumRadioTherapy' />
                                        }
                                        key='6'
                                        extra={genExtra(6)}
                                    >
                                        <RadioTherapyByCesiumPage
                                            caseId={Number(caseId)}
                                            planId={data?.id}
                                        />
                                    </Panel>
                                )
                            }
                        })}
                        {panelPlan.map((tab) => {
                            const userAllowed = tab.allowedRoles.some(e => userRoles?.includes(e));
                            if (tab.name == 'RadioTherapyByCobalt' && userAllowed) {
                                setCobalt(true); 
                                return (
                                    <Panel
                                        header={
                                            <FormattedMessage id='CobaltRadioTherapy' />
                                        }
                                        key='7'
                                        extra={genExtra(7)}
                                    >
                                        <RadioTherapyByCobaltPage
                                            caseId={Number(caseId)}
                                            planId={data?.id}
                                        />
                                    </Panel>
                                )
                            }
                        })}

                        {panelPlan.map((tab) => {
                            const userAllowed = tab.allowedRoles.some(e => userRoles?.includes(e));
                            if (tab.name == 'RadioTherapyByLinac' && userAllowed) {
                                setLinac(true); 
                                return (
                                    <Panel
                                        header={
                                            <FormattedMessage id='LinacRadioTherapy' />
                                        }
                                        key='8'
                                        extra={genExtra(8)}
                                    >
                                        <RadioTherapyByLinacPage
                                            caseId={Number(caseId)}
                                            planId={data?.id}
                                        />
                                    </Panel>
                                )
                            }
                        })}
                        {panelPlan.map((tab) => {
                            const userAllowed = tab.allowedRoles.some(e => userRoles?.includes(e));
                            if (tab.name == 'RadioTherapyByIodine' && userAllowed) {
                                setIodin(true); 
                                return (
                                    <Panel
                                        header={
                                            <FormattedMessage id='IodineRadioTherapy' />
                                        }
                                        key='9'
                                        extra={genExtra(9)}
                                    >
                                        <RadioTherapyByIodinePage
                                            caseId={Number(caseId)}
                                            planId={data?.id}
                                        />
                                    </Panel>

                                )
                            }
                        })}


                    </Collapse>
                </Col>
            )}

            {panelPlan.map((tab) => {
                const userAllowed = tab.allowedRoles.some(e => userRoles?.includes(e));
                if (tab.name == 'Examination' && userAllowed) {
                    setExaminationCalled(true)
                    return (
                        <>
                            <Divider style={{ marginTop: '10px', marginBottom: '10px' }} />
                            {(type === 'Details' || type === 'Update') && (
                                <Col span={24}>
                                    <Collapse accordion>
                                        <Panel
                                            header={<FormattedMessage id='examinations' />}
                                            key='0'
                                            extra={genExtra(0)}
                                            style={{ backgroundColor: '#99d9ea' }}
                                        >
                                            <ExaminationPage
                                                planId={data?.id}
                                                caseId={Number(caseId)}
                                            />
                                        </Panel>
                                    </Collapse>
                                </Col>
                            )}
                        </>

                    )
                }
            })}


        </Row>
    );
};

export default PlanForm;
Pandaiolo

You are calling setState functions (such as setAnalysisCalled) in the render method. In your case, IIUC, when some tab is active, it will call that function during the rendering of the component. That will cause another re-render, and so on forever.

I am not sure of the architecture of your component, but this pattern is not forbidden per se, even if, instead of analysisCalled, maybe you don't need that additional variable, you could use the same condition as what made the tab or color, etc. display in that case?

Anyway, if you still need to call setState in the render method, and to avoid infinite loop, you have to check the current value.

So, instead of:

setAnalysisCalled(true);

You would do:

if (!analysisCalled) setAnalysisCalled(true);

So that it will not re-run at the next re-render, when the value is already true.

Same for all other setAbcd called inside the render method.

Edit:

More detailed suggestion about using derivative data instead of a new boolean:

instead of:

const [examinationCalled, setExaminationCalled] = useState(false)
...
if (tab.name == 'Examination' && userAllowed) {
                    setExaminationCalled(true)
...

You can use more efficient code as following:

const tab = panelPlan.find(tab => tab.name === 'Examination')
const examinationEnabled =  = tab.allowedRoles.some(e => userRoles?.includes(e))

Actually, you could have a map of allowed roles, such as:

const allowed = panelPlan.reduce((res, tab) => {
   res[tab.name] = tab.allowedRoles.some(e => userRoles?.includes(e))
   return res
}, {})

That would allow, in your queries, to check allowance like so:

// Example for Examination
enabled: allowed['Examination']

Last suggestion: wherever you have a map to set a value in your component, it is a good idea to wrap it in a useMemo so that it is only computed when the dependencies of that useMemo change, leading to snappier UI.

Example with my allowed derived state above:

const allowed = useMemo(() => panelPlan.reduce((res, tab) => {
   res[tab.name] = tab.allowedRoles.some(e => userRoles?.includes(e))
   return res
}, {}), [panelPlan])

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop - ProtectedRoutes Component

Uncaught Invariant Violation: Too many re-renders. React limits the number of renders to prevent an infinite loop

Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. (React-js)

Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. (Next-js) Toggle Component

Error: Too many re-renders. React limits the number of renders to prevent an infinite loop React Native

react usestate Error: Too many re-renders. React limits the number of renders to prevent an infinite loop

React giving me Error: Too many re-renders. React limits the number of renders to prevent an infinite loop

React : Error: Too many re-renders. React limits the number of renders to prevent an infinite loop

received this error "Error: Too many re-renders. React limits the number of renders to prevent an infinite loop."

Error: "Too many re-renders. React limits the number of renders to prevent an infinite loop"

Too many re-renders. React limits the number of renders to prevent an infinite loop. Next js error

"Error: Too many re-renders. React limits the number of renders to prevent an infinite loop."

error too many re-renders. react limits the number of renders to prevent an infinite loop

useState and if statement causing Error: Too many re-renders. React limits the number of renders to prevent an infinite loop

Too many re-renders. React limits the number of renders to prevent an infinite loop-error

Error: Too many re-renders. React limits the number of renders to prevent an infinite loop when using useState()

Error: Too many re-renders. React limits the number of renders to prevent an infinite loop [another variant]

Too many re-renders. React limits the number of renders to prevent an infinite loop. with for loop

Too many re-renders. React Limits the number of renders to prevent an infinite loop - React hooks

React Native issue - Too many re-renders. React limits the number of renders to prevent an infinite loop

React Js : Too many re-renders. React limits the number of renders to prevent an infinite loop

Too many re-renders. React limits the number of renders to prevent an infinite loop. - React Hooks

React redux Too many re-renders.React limits the number of renders to prevent an infinite loop

Too many re-renders. React limits the number of renders to prevent an infinite loop | React Native

React Native: Too many re-renders. React limits the number of renders to prevent an infinite loop

I am getting this error "Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop." When trying the code

ReactJS, react-bootstrap, Modal Box: "Error: Too many re-renders. React limits the number of renders to prevent an infinite loop."

React: setting a state Hook causes error - Too many re-renders. React limits the number of renders to prevent an infinite loop

Too many re-renders. React limits the number of renders to prevent an infinite loop