Sharing data between siblings w/tabs - reactjs

I'm using chakra-ui to build a web app, in which I have three tabs, each with their own state. The state of each tab should be shared between all the other tabs. But if I lift up all the states to the parent and pass them as props to each tab, it gets laggy because every time I change something in a tab, it rerenders everything.
Are there other ways to share data between them or, if only lift state up works, prevent rerender of inactive tabs?
<Tabs>
<TabList>
<Tab>Cálculos</Tab>
<Tab>Gráficos</Tab>
<Tab>Resultados</Tab>
</TabList>
<Stack direction='row'>
<TabPanels >
<TabPanel m={0} p={0} w='full' h='full'>
<Calculations testStarted={testStarted} />
</TabPanel>
<TabPanel m={0} p={0} w='full' h='full'>
<Graphics testStarted={testStarted} />
</TabPanel>
<TabPanel m={0} p={0} w='full' h='full'>
<Results testStarted={testStarted} />
</TabPanel>
</TabPanels>
</Stack>
</Tabs>

You can use useContext
React Beta docs has a good visual tutorial on this:
https://beta.reactjs.org/learn/passing-data-deeply-with-context

Related

How to fix React-tab issues

I am trying to implement react tabs in my Next.js applications. I have installed react tab packages and put the code but unfortunately, it doesn't work.
When I click on title 1 it doesn't move any content 1 same as clicking title2.
But the same code works in a new React application. Below is the code:
const Rtab = () => {
return(
<Tabs>
<TabList>
<Tab>Title 1</Tab>
<Tab>Title 2</Tab>
</TabList>
<TabPanel>
<h2>Any content 1</h2>
</TabPanel>
<TabPanel>
<h2>Any content 2</h2>
</TabPanel>
</Tabs>
);
}

How to Right align a link inside an AppBar next to Tabs for Material UI?

Still relatively new to Material UI and ReactJS.
But I'm trying to have a set of tabs at the top of the page, but I also want a Logout link to the right side of the tabs.
Here's what I have
<AppBar position="static">
<Tabs
value={value}
onChange={handleChange}
aria-label="simple tabs example"
style={{flex:1}}
>
<Tab label="Approvals" />
<Tab label="Members" />
</Tabs>
Logout
</AppBar>
But the logout link isn't aligned to the right and is on a new line underneath the Tabs.
How would I go about having it sit at the end of the tabs?
I think it can help you. Add between and Logout button.
<AppBar position="static">
<Toolbar>
<Tabs
value={value}
onChange={handleChange}
aria-label="simple tabs example"
>
<Tab label="Approvals" />
<Tab label="Members" />
</Tabs>
<Box flexGrow={1} />
<Button>Logout</Button>
</Toolbar>
</AppBar>

What does it mean {...a11yProps(0)} in the component property?

Consider the following code snippet of a component:
...
...
function a11yProps(index: any) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}
...
...
return (
<div className={classes.root}>
<AppBar position="static">
<Tabs value={value} onChange={handleChange} aria-label="simple tabs example">
<Tab label="Item One" {...a11yProps(0)} />
<Tab label="Item Two" {...a11yProps(1)} />
<Tab label="Item Three" {...a11yProps(2)} />
</Tabs>
</AppBar>
<TabPanel value={value} index={0}>
Item One
</TabPanel>
<TabPanel value={value} index={1}>
Item Two
</TabPanel>
<TabPanel value={value} index={2}>
Item Three
</TabPanel>
</div>
);
}
I struggle to understand the following component implementation:
<Tab label="Item One" {...a11yProps(0)} />
What does {...a11yProps(0)} mean? Does it mean I pass here properties?
When I look at the API documentation of Tab, I can not find the id and aria-controls properties.
The whole code https://codesandbox.io/s/kz25m
It is a spread operator (... is Javascript spread operator). It basically de-structures / spreads out the value from an array or object.
In your sample code I see your function returns some javascript object. This spread operator pulls out / de-structures all the values from the object and gives each individual values as output
{... a11yProps(0)}
==> This would return -> {...{id: `simple-tab-0`,aria-controls: `simple-tabpanel-0`}}
==> on spreading out the values from the object it would look like
=> {id: `simple-tab-0`,aria-controls: `simple-tabpanel-0`}
Another example with spread operator
let d = {...{"a":1, "b":2, "c":3}}
output: {a: 1, b: 2, c: 3}
Please refer to ES6 website for more on spread operator, destructuring - http://es6-features.org/#SpreadOperator
It's just a function for making a dynamic object and using them as props, to reduce code size.
<Tab label="Item One" id="simple-tab-0" ariaControls="simple-tabpanel-0"/>
About TypeScript and Docs: If you ctrl + click on the Material-UI component, you can see they extends types of component with React.ElementType and inside of this, you can find JSX.IntrinsicElements and each one of HTML element has React.DetailedHTMLProps with props of HTMLAttributes extended with AriaAttributes and DOMAttributes. So naturally, you can pass all of the available attributes for that tag on them!

Navigate between react tabs on button click

I am new to React. I am using React web tabs to create tabs in react.
How would one go about triggering a change of tab panels upon clicking a button element, I have two button, "Previous" & "Next". On click of previous button , i want to go to previous tab & On next button click it should show next tab ?
<Tabs defaultTab="one" vertical className="vertical-tabs" selectedIndex={this.state.selectedTabIndex}
onSelect={this.handleSelect}>
<TabList>
<Tab tabFor="one" >BASIC INFORMATION</Tab>
<Tab tabFor="two" >ADVANCED INFORMATION</Tab>
<Tab tabFor="three">ASSIGN USERS</Tab>
<Tab tabFor="four" >TEMPLATE</Tab>
</TabList>
<TabPanel tabId="one">
//BASIC INFORMATION
</TabPanel>
<TabPanel tabId="two">
//ADVANCED INFORMATION
</TabPanel>
<TabPanel tabId="three">
//ASSIGN USERS
</TabPanel>
<TabPanel tabId="four">
//TEMPLATE
</TabPanel>
{
<div>
<Button onClick={()=>this.handlePreviousBtnChange()}>Back</Button>
</div>}{<div>
<Button onClick={()=>this.handleNextBtnChange()}>Next</Button>
</div>}
</Tabs>
Please help me.Thanks in advance
According to this closed issue on the project, you should be able to use defaultTab to programmatically change the selected tab. https://github.com/marcuslindfeldt/react-web-tabs/issues/10#issuecomment-482846520
Here's a short example. I made the tab ids numbers to make incrementing/decrementing easier.
const ControllableTabs = () => {
const [selectedTab, setSelectedTab] = useState(0);
const tabCount = 3;
return (
<>
<Tabs defaultTab={selectedTab.toString()}>
<TabList>
<Tab tabFor="0">Tab 1</Tab>
<Tab tabFor="1">Tab 2</Tab>
<Tab tabFor="2">Tab 3</Tab>
</TabList>
<TabPanel tabId="0">
<p>Tab 1 content</p>
</TabPanel>
<TabPanel tabId="1">
<p>Tab 2 content</p>
</TabPanel>
<TabPanel tabId="2">
<p>Tab 3 content</p>
</TabPanel>
</Tabs>
<Button onClick={() => setSelectedTab((selectedTab + tabCount - 1) % tabCount )}>Back</Button>
<Button onClick={() => setSelectedTab((selectedTab + 1) % tabCount )}>Next</Button>
</>
);
}
I should note that there are other libraries that possibly suit your needs better, depending on the functionality that you desire. If you happen to be using material-ui in your project already, the Stepper component provides much more customizability. https://material-ui.com/components/steppers/#stepper

How to make vertical tabs with React

Can someone provide me with a way to create vertical tabs using React?
I experimented with various npm packages like react-web-tabs,reactstrap and react-bootstrap.The last two only had examples for horizontal tabs.React-web-tabs has a vertical tab example in their docs but it doesn't work.
import { Tabs, Tab, TabPanel, TabList } from 'react-web-tabs';
class NewNavigation extends React.Component{
render(){
return(
<Tabs defaultTab="vertical-tab-one" vertical>
<TabList>
<Tab tabFor="vertical-tab-one">Tab 1</Tab>
<Tab tabFor="vertical-tab-two">Tab 2</Tab>
<Tab tabFor="vertical-tab-three">Tab 3</Tab>
</TabList>
<TabPanel tabId="vertical-tab-one">
<p>Tab 1 content</p>
</TabPanel>
<TabPanel tabId="vertical-tab-two">
<p>Tab content</p>
</TabPanel>
<TabPanel tabId="vertical-tab-three">
<p>Tab 3 content</p>
</TabPanel>
</Tabs>
);
}
}
By now, it displays basic horizontal tabs and I want to fix this code as it displays vertical tabs.It is also highly appreciated if you recommend any other way.
By adding following CSS will do the trick for you:
.rwt__tab {
width: 100%
}
Another way is to import the CSS file in your component by adding the following line:
import 'react-web-tabs/dist/react-web-tabs.css';
Here is the example if for your reference.

Resources