Reputation: 305
I have Tab navigator that handles data changing of itself and other two sibling component.
Main parent Component that does data fetching and manipulation based on three sentiments: positive, negative and neutral as request body parameter in http post request.
Second parent component that stores all positive data, negative data and neutral data from main parent component.
Then three Child Components: Table one and Tab Navigation.
The Tab navigation has three three tabs namely: Positive, Negative and Neutral.
As soon as the page renders on first load, by default (without clicking positive tab button), it fetches positive data and displays it in all three child components. Then on clicking on Negative tab, it should display negative data in all three child components i.e. Table one and under negative tab of tab navigation. Same thing follows for Neutral Tab.
In short, Tab navigation handles data rendering of it's self and sibling components based on its active state and getting that data from parent component.
I tried passing the active event from tab navigation to its upper container but it doesn't seem to work fine.
Tab.js
import React, { Component } from 'react';
export default class Tab extends Component
{
constructor(props)
{
super(props);
this.state =
{
active: 'positive',
}
}
toggle = (event) =>
{
this.setState({
active: event
})
this.props.sendEvent(this.state.active);
}
get_tab_content =()=>
{
switch(this.state.active)
{
case 'positive':
return <div><SomeDataComponent1 positiveprops={} /></div>;
case 'negative':
return <div><SomeDataComponent2 negativeprops={}/></div>;
case 'neutral':
return <div><SomeDataComponent3 neutralprops={} /></div>;
default :
}
}
render() {
const tabStyles = {
display: 'flex',
justifyContent: 'center',
listStyleType: 'none',
cursor: 'pointer',
width: '100px',
padding: 5,
margin: 4,
fontSize: 20,
color: 'green'
}
const tabStyles2 = {
display: 'flex',
justifyContent: 'center',
listStyleType: 'none',
cursor: 'pointer',
width: '100px',
padding: 5,
margin: 4,
fontSize: 20,
color: 'red'
}
const tabStyles3 = {
display: 'flex',
justifyContent: 'center',
listStyleType: 'none',
cursor: 'pointer',
width: '100px',
padding: 5,
margin: 4,
fontSize: 20,
color: 'yellow'
}
const linkStyles = {
display: 'flex',
justifyContent: 'center',
color: '#000',
listStyleType: 'none'
}
const divStyle = {
border: '1px solid #34baa2',
width: '450px'
}
const box = this.get_tab_content()
return (
<div style={divStyle} >
<ul style={linkStyles}>
<li style={tabStyles} onClick={function(){this.toggle('positive')}.bind(this)}>Positive</li>
<li style={tabStyles2} onClick={function(){this.toggle('negative')}.bind(this)}>Negative</li>
<li style={tabStyles3} onClick={function(){this.toggle('neutral')}.bind(this)}>Neutral</li>
</ul>
<div>
{box}
</div>
</div>
);
}
}
Second Parent Component.js
import React,{Component} from 'react';
import Tab from '../tab/tab';
import MentionTable from '../table/table';
class DataCharts extends Component{
constructor(props){
super(props);
this.state = {
childEvent: ''
}
}
getEvent = (childevent) => {
this.setState({
childEvent: childevent
});
console.log(this.state.childEvent)
}
render(){
const {positivetable,positivewords, negativetable, negativewords, neutraltable, neutralwords } = this.props;
return(
<div style={{display:'flex', flexDirection: 'row'}}>
<Table />
<Tab sendEvent={this.getEvent}/>
</div>
)
}
}
export default DataCharts;
Upvotes: 3
Views: 2542
Reputation: 53884
The problem with your code is the next lines:
toggle = event => {
this.setState({
active: event
});
this.props.sendEvent(this.state.active);
};
setState
is asynchronous, so you sending to sendEvent
the not intended state.
toggle = event => {
this.setState(prevState => {
console.log('prevState', prevState);
console.log(event);
this.props.sendEvent(event);
return { active: event };
});
};
Upvotes: 1
Reputation: 1659
I think calling the parent function in setState
callback would work, for thet we need to do it like this in Tab.js
this.setState({
active: event
}, () => { this.props.sendEvent(this.state.active)})
also console.log(this.state.childEvent)
should be also in callback too so that you get the state after it has been updated, we need to change DataCharts.js too
this.setState({
childEvent: childevent
}, () => { console.log(this.state.childEvent)})
Working demo -: https://stackblitz.com/edit/react-zhbmad
Upvotes: 1