Search code examples
javascriptreactjstabsreact-tabs

React-tabs: Uncaught TypeError: Cannot read property 'data' of null, when switching back to main tab?


I have a Main.js which is a React class that consolidates other React classes. This works well, but I now want to have three tabs; The first containing the aforementioned Main.js, but the others containing different things.

Using react-tabs I've successfully managed to get it done. There are three tabs as created here:

<Tabs>
    <TabList>
        <Tab>Main</Tab>
        <Tab>Second</Tab>
        <Tab>Third</Tab>
    </TabList>
     <TabPanel>
        Main goes here.
     </TabPanel>
     <TabPanel>
        Second goes here.
     </TabPanel>
     <TabPanel>
        Third goes here.
     </TabPanel>
</Tabs>

The Main tab renders and displays just fine. However, if I click to, say, the Second tab, and then back to Main, I will get the following error: TypeError: Cannot read property 'data' of null.

I see where I get the error; namely the first time data from this.state is being used.

What is going wrong? Is it because it is trying to re-render the entire Main component instead of saving the state?

Edit: Here are some pointers to how state is managed in this Main component.

getInitialState: function() {
        return { data : {
            info : {},
            hist : {},
            grouped : {},
            cars : {},
            user : "",
            map :  {},
        }}},

We instantiate the values above as empty.

When component mounts, it's populated as such:

componentDidMount : function() {
    this.loadData();
    setInterval(this.loadData, 60000);
}

Where it'll load every 60 seconds.

The loadData function is something along these lines:

loadData : function() {
        console.info("Loading data.. ");
                $.ajax({
        url: this.props.prefix_url + "/api",
        dataType: 'json',
        cache: false,
        success: function(data) {
            console.info("Received backend data ");
            this.setState({data: data }); // Attach data to the empty values
// .. Goes on

Solution

  • The solution was to add forceRenderTabPanel={true} to the tabs as such: <Tabs forceRenderTabPanel={true}> , this will keep track of the state across all three tabs and not just the one you are on.