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
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.