Boky Boky - 2 months ago 7
Javascript Question

React JS state doesn't update on click

My showroom component is as follows :

export default class Showrooms extends React.Component {
constructor(props){
super(props);

this.state = {
blockView: true
};
}

handleChangeView(view){
console.log(view);
this.setState({blockView: view});
}

render(){
const language = this.props.language;
return (
<div className="col-lg-10 col-md-9 col-sm-9 col-xs-12 text-center">
<div className="lists">
<div className="listsTitle">{language.portal.introPageTitle}</div>

<ViewBar handleChangeView={this.handleChangeView.bind(this)}/>

<div className="allLists">
<div className="view">

{this.props.allLists.map( (list, i) => <View key={i} list={list} language={language} blockView={this.state.blockView}/>)}

<div className="clearfix"/>
</div>
</div>
<div className="clearfix"/>

</div>
</div>
);
}
}


and my viewBar component is as follows :

export default class ViewBar extends React.Component {
constructor(props){
super(props);
this.state = {
blockView: true
};
}

setBlockView(event){
event.preventDefault();
this.setState({blockView: true}, this.props.handleChangeView(this.state.blockView));
}

setListView(event){
event.preventDefault();
this.setState({blockView: false}, this.props.handleChangeView(this.state.blockView));
}


render(){
let blockViewAddBorder = this.state.blockView ? "activeView" : "";
let listViewAddBorder = !this.state.blockView ? "activeView" : "";
return (
<div className="viewBar">
<Link to="" onClick={this.setListView.bind(this)} className={`listViewIcon ${listViewAddBorder}`}>
<FontAwesome name="list" className="portalFaIcon"/>
</Link>
<Link to="" onClick={this.setBlockView.bind(this)} className={blockViewAddBorder}>
<FontAwesome name="th-large" className="portalFaIcon"/>
</Link>
</div>
)
}
}


In viewBar component I have two onClick functions where I update the state and the I call an function from showroom component to update the state.

Depending on that state I change the way how I display the content.

But the problem is, when the function setListView is called first time, the state doesn't change to false. When I second time call setListView then it sets the state to false.

this.props.handleChangeView
function is an callback function, and it should be called after the state is updated.

Any advice?

Answer

Second argument in setState should be function

this.setState({ blockView: true }, () => {
   this.props.handleChangeView(this.state.blockView);
}) 

in your example, you pass result to setState from handleChangeView

this.setState({
  blockView: true
}, this.props.handleChangeView(this.state.blockView));

handleChangeView returns nothing, it means that you pass to setState undefined

this.setState({
  blockView: true
}, undefined);

so you don't call handleChangeView after setState

Comments