'Chakra UI, Tabs onChange method throws Maximum update depth exceeded on state change

I have the following code, React throws Maximum update depth exceeded error, whenever I change the change the index, It is somehow forming an infinite loop, and the onChange method is being called on render, how can I fix it?


const ChecklistNavbarTabs = () => {
    const [tabIndex, setTabIndex] = useState(0);

    return (
        <Tabs
            variant='unstyled'
            alignItems='center'
            width='full'
            bgColor='header.100'
            height='full'
            onChange={(index:number)=>{setTabIndex(index)}}
        >
            <TabList color='blackAlpha.600' justifyContent='space-between' m='3'>
                <Flex
                    alignContent='space-between'
                    borderRadius='4'
                    justifyContent='space-between'
                    border='1px solid'
                    borderColor='blackAlpha.500'
                >
                    <Flex justifyContent='space-between'>
                        <Flex>
                            <Tab
                                bgColor='gray.100'
                                borderColor='blackAlpha.500'
                                border='1px solid'
                            >
                                <Text>Header Fields</Text>
                            </Tab>
                        </Flex>
                        <Flex>
                            <Tab
                                bgColor='gray.100'
                                borderColor='blackAlpha.500'
                                border='1px solid'
                            >
                                <Text>Checkpoint</Text>
                            </Tab>
                        </Flex>
                        <Flex>
                            <Tab
                                bgColor='gray.100'
                                borderColor='blackAlpha.500'
                                border='1px solid'
                            >
                                <Text>Checklist Item</Text>
                            </Tab>
                        </Flex>
                        <Flex>
                            <Tab
                                bgColor='gray.100'
                                borderColor='blackAlpha.500'
                                border='1px solid'
                            >
                                <Text>Footer Field</Text>
                            </Tab>
                        </Flex>
                    </Flex>
                </Flex>
                <Flex justifyContent='flex-end' flex='1'>
                    <AddHeaderFieldButton />
                </Flex>
            </TabList>
            <Flex>
                <TabPanels>
                    <TabPanel>
                        <ChecklistHeaderFieldTable table={navbarData} />
                    </TabPanel>
                    <TabPanel>
                        <CreateCheckpointTable table={CreateCheckPointData} />
                    </TabPanel>
                    <TabPanel>
                        {/* <CreateChecklistItemTable table={AddChecklistItemData} /> */}
                    </TabPanel>
                    <TabPanel>
                        {/* <ChecklistFooterTable table={AddFooterTableData} /> */}
                    </TabPanel>
                </TabPanels>
            </Flex>
        </Tabs>
    );
};

export default ChecklistNavbarTabs;

I have tried, useMemo and useCallback as well, to memoize the results and stop re-render though I don't know if that the right way.

Please help me solve this error.



Solution 1:[1]

The documentation says the following:

You can render any element within Tabs, but TabList should only have Tab as children, and TabPanels should have TabPanel as children.

Tabs expects TabList and TabPanels as children. The order doesn't matter, you can have TabList at the top, at the bottom, or both.

I believe nesting Tab inside of multiple Flex components is the cause of the onChange infinite loop issue. Tab should be a direct child of TabList. You'd likely also need to remove <AddHeaderFieldButton /> or place it inside of a Tab component. Also TabPanels should not be wrapped in a Flex component.

Solution 2:[2]

The cause of the problem was that the tab panels had react-table tables as children, and there was an issue that I did not use useMemo while declaring table headers.

simply then fixed it via useMemo

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Stafford Rose
Solution 2 Himanshu Jangid