I need to use the TabComponent from Syncfusion to show some files in a web app. There can be a lot of files, but I only want to show them one by one in my tabs. And if I want to show only one file, I also DON'T want to store all the other files at the start of the page. I just want to load the file that is shown, and all the other ones will be called later, when the user wants to see them and only at that moment to avoid too much charge in the storage.
So I tried a few things to be able to have an empty div in the hidden tabs, and something shown in the focused tab. This example is just about updating a filled div to an empty one and vice versa.
import { TabComponent, TabItemDirective, TabItemsDirective } from '@syncfusion/ej2-react-navigations';
import * as React from 'react';
import { useState } from 'react'
import ReactDOMServer from 'react-dom/server'
const Tab = (props) => {
const tabContent = (data) => {
return ReactDOMServer.renderToStaticMarkup(data);
};
const headertext = [{ text: 'Header1', id: "0" }, { text: 'Header2', id: "1" }, { text: 'Header3', id: "3" }];
const [chosenItem, setChosenItem] = useState(1)
const [counter, setCounter] = useState(0)
const contentToBeShown = [<div>Content1</div>, <div>Content2</div>, <div>Content{counter}</div>];
const [content, setContent] = useState(contentToBeShown)
const selecting = (args) => {
setCounter(counter + 1)
console.log(args)
content.forEach((item, index) => {
if(index !== args.selectingIndex){
content[index] = (<div>no</div>)
}else{
console.log("Before content", content, "contentToBeShown", contentToBeShown)
content[index] = contentToBeShown[index]
console.log("After content", content, "contentToBeShown", contentToBeShown[index])
}
})
}
return (
<div className="control-pane">
<div className="control-section tab-control-section">
{/* Render the Tab Component */}
<TabComponent overflowMode="Scrollable" id="defaultTab" selecting={selecting} selectedItem={chosenItem}>
<TabItemsDirective>
{
// Create TabItemDirective model dynamically
headertext.map((item, index) => {
return <TabItemDirective presentation={true} key={index} header={item} content={{template: tabContent, data: content[index]}}/>
})
}
</TabItemsDirective>
</TabComponent>
</div>
</div>
);
}
export default Tab;
With this code, I can see that the focused tab is SUPPOSED to return my div with its simple content. In the console.log, the content changes from the "no" div to the filled div, just as expected. But, on the rendered page, the old "no" div is still shown. It feels like there is something about the selecting function happening too late in the rendering process to show the right content but even here I might be wrong. What causes the failed rendering and how can I get around this problem ?
I understood what was the problem : It was simply the way that I was updating the array "content" in the state.
Instead of doing :
content[index] = (<div>no</div>)
You have to update an array in a state like this :
var newContent = []
content.forEach((item, index) => {
var updateContent = (<div>no</div>)
if(index === args.selectingIndex){
updateContent = contentToBeShown[index]
}
newContent.push(updateContent)
})
setContent(newContent)