In ReactJS, can you ensure that a method of the class is only executed after setState is completed?

2

I'm doing a FreeCodeCamp project using ReactJS. It consists of making two Leaderboards : one of the campers with the highest score in the last 30 days and another of those who have accumulated more points, user can choose which leaderboard to see at the moment. I made the exchange possible by clicking on the title element of the table. However, I'm experiencing problems because setState() is asynchronous.

You now need to click 2x so that the table changes, instead of one. I used some consoles.log to debug and I believe that the method I created to manage fetch getFetch() is running before the state changes.

And I wonder if it's possible to ensure that the getFetch() method is only executed after setState is complete?

I've tried using async / await and callback , but it did not work. In addition I already looked for solutions in the documentation and in other sites, but none suggested worked (or it was me that I could not implement).

Follow the code snippet where the state changes and the preview link

const allTimeApi ='https://fcctop100.herokuapp.com/api/fccusers/top/alltime'
const recentApi = 'https://fcctop100.herokuapp.com/api/fccusers/top/recent'

class TableContent extends React.Component{
 constructor(props){
  super(props)
  this.state = {
   allTimeRequested:false,
   usersData:[],
  }};

 getFetch(){
  fetch(this.state.allTimeRequested? allTimeApi : recentApi)
   .then(results => results.json())
   .then(data => {
     let tableData = data.map((user,index)=>(
      <tr key={user.username} style={{textAlign: 'center'}}>
        <th>{index+1}</th>
        <td>
          <img 
            src={user.img}
            className="profilePhotos" 
            alt={'${user.username} profile photo'}/>
          <a 
           href={'https://www.freecodecamp.com/${user.username}'}>
           {user.username}</a>
        </td>
        <td>{user.recent}</td>
        <td>{user.alltime}</td>
      </tr>
      ))
      this.setState({
        usersData: tableData,
      })
  })
 }

 /*Gostaria de fazer o getFetch ser exec após o setState nos dois métodos abaixo*/

 showBestRecent = () => {
  this.setState({allTimeRequested:false})
  this.getFetch()
 }

 showBestAllTime = () => {
  this.setState({allTimeRequested:true})
  this.getFetch()
 }

 componentDidMount(){
  this.getFetch()
 }

 render(){
  return(
   <div className="col-12" style={{textAlign: 'center'}}>
    <table className="table table-striped table-bordered tableShadow">
     <th>#</th>
     <th>Camper name</th>

      <th 
       className={this.state.allTimeRequested? 
       "notSelected":"selected grad"}
       onClick={this.showBestRecent}>Points in past 30 days</th>

      <th 
       className={this.state.allTimeRequested?
       "selected grad":"notSelected"} 
       onClick={this.showBestAllTime}>All time points</th>

     <tbody>
      {this.state.usersData}
     </tbody>
    </table>
   </div>
   )} 
 }

Tried Solutions:

Async / await:

When doing this, nothing is rendered on the screen, I tried two ways

form 1:

 showBestRecent = async () => {
  await this.setState({allTimeRequested:false})
  this.getFetch()
 }

Form 2:

showBestRecent = async () => {
 await this.setState({allTimeRequested:false})
.then(this.getFetch())
}

callback:

When I do this, the state changes (I realize because of the style change in the table header element) but it is as if the getFetch function was not executed (the table does not change)

 showBestRecent = () => {
  this.setState({allTimeRequested:false}),
  () => this.getFetch()
 }

If I made some grotesque mistake, I apologize. I'm still new to JS and React

    
asked by anonymous 04.02.2018 / 19:11

1 answer

1

I asked the FreeCodeCamp group in my city and got an answer that worked. I was in doubt whether to delete the question or not, but I thought someone might want to know. Anyway, I made the wrong callback.

Right Form

showBestRecent = () => {
 this.setState({allTimeRequested:false},()=>this.getFetch())
}

I had not passed the function as a parameter of setState()

    
04.02.2018 / 20:53