George Bleasdale
George Bleasdale

Reputation: 351

State is always one step behind (setState async problems) - React js

I have three components:

The problem I'm having is that the state of each component is always one step behind. I realise that this is because setState is asynchronous but I'm not sure what's the best way to get around that. I've read a few possible solutions but I'm not sure how best to implement them in my setup. Can anyone advise?

Here is PageBuilder (I've cut it down for clarity):

  constructor(props){
    super(props);
    this.state = {
    pageTitle: '', pageDesc:'', items: [], id:''
 };
}
updateTitle = (e) => {
  this.setState({pageTitle: e.target.value});
}

updateDesc = (e) => {
  this.setState({pageDesc: e.target.value});
}

addNewPage = () => {
  let info = {...this.state};
  this.props.callBack(info);
}

render() {
          return (
 <input className="pageTitleField" type="text" placeholder="Page Title" 
value={this.state.pageTitle} onChange={this.updateTitle}></input>

 <textarea className="pageDescField" placeholder="Page description..." 
  onChange={this.updateDesc}></textarea>

<button onClick={this.addNewPage}>New Page</button>
 )
  }

PageUpdater:

export class PageUpdater extends React.Component{
constructor(props){
super(props);
this.state={
  data: ''
}
}
 updatePageList = (pageAdded) =>{
this.setState({data:pageAdded});
console.log(this.state)
 }

render(){
   return(
     <div>
     <PageBuilder callBack={this.updatePageList} />
     <PageList addToList={this.state.data} />
  </div>
)}}

PageList:

export class PageList extends React.Component{
   constructor(props){
    super(props);
    this.state = {pages:''}
    }

 componentWillReceiveProps(props) {

   this.setState({pages: [...this.state.pages, this.props.addToList]})
  }

  getPages = () => {
      var pages = []
       for(var key in this.state.pages){
         pages.push(this.state.pages[key].pageTitle)}
       return pages // Return an array with the names
 }


 render(){
   return(
         <div>
         {this.getPages().map((page, index) => <li key={index}>{page} 
         </li>)}
      </div>
       )}}

Upvotes: 2

Views: 1718

Answers (1)

semanser
semanser

Reputation: 2348

Inside of componentWillReceiveProps this.props refers to the previous version of props. But what you need is to use the latest version of props.

Instead of

componentWillReceiveProps(props) {
   this.setState({pages: [...this.state.pages, this.props.addToList]})
}

You should write

componentWillReceiveProps(nextProps) {
   this.setState({pages: [...this.state.pages, nextProps.addToList]}) // notice the difference this.props vs nextProps
}

Upvotes: 1

Related Questions