Search code examples
javascriptreactjsextjsextreact

While using TabPanel only render active tab and only the first time


I'm creating an application with multiple tabs using ExtReact TabPanel component. The default behavior appears to be that all tabs are rendered during rendering of the TabPanel. However, I only want to render only the active tab and render it only the first time clicked (that is unless the user does something within the tab to require rerender). I've been playing with listeners and the activate event but I'm just not that familiar with the control set to know what I'm doing. Below is what I have so far and it appears the tabs are rendering even before the activate event is fired so not sure if that is the correct place for this.

<TabPanel 
            id="adminTabs"
            flex={1}
            shadow 
            defaults={{
                cls: "card",
                layout: "center"
            }}
            listeners= {{
                scope: this,
                activate: (newActiveItem, tab, oldActiveItem, eOpts) => {
                    //alert(JSON.stringify(newActiveItem.id))
                },
                //activeItemChange: ( sender, value, oldValue, eOpts ) => {
                //    alert(value.id)
                //    alert(oldValue.id)
                //}
            }}
        >
            <Container id="lookupsTab" title="Lookups" layout="center">
                <Container layout="fit" fullscreen><LookupsLanding/></Container>
            </Container>
            <Container title="Configuration" layout="center">
                <Container>Configuration Content</Container>
            </Container>
            <Container id="usersTab" title="Users" layout="center">
                <Container layout="fit" fullscreen><UsersLanding/></Container>
            </Container>
            <Container title="Application Errors" layout="center">
                <Container>Application Errors Content</Container>                
            </Container>
        </TabPanel>

Solution

  • I ended up solving this by just tracking the activated tabs in the component state. On the TabPanel.onActiveItemChange I call a function that will record which tab was clicked and store it in the component state like so:

    handleTabClick = (sender, value, oldValue, eOpts) => {
        let { activatedTabs } = this.state;
        if (!activatedTabs.includes(value.id)){
            activatedTabs.push(value.id);
            this.setState({ activatedTabs: activatedTabs })
        }
    }
    

    Then on each of my tabs I have them wrapped in a state check:

    render(){
        const { activatedTabs } = this.state;
        ...
        {   activatedTabs.includes("lookupsTab") ? (
               <Container layout="fit" fullscreen><LookupsLanding/</Container>
            ) : null                        
        }