2017-01-03 4 views
0

Я работаю на этом FreeCodeCamp таблице лидеров таблицы и и при нажатии на выделенном столе заголовка приложение вызывает либо этот адрес https://fcctop100.herokuapp.com/api/fccusers/top/недавний или это один https://fcctop100.herokuapp.com/api/fccusers/top/Alltime таким образом сортировки между кемперов с наивысшие баллы за за последние 30 дней или все время.ReactJS государства, не изменяя

Моя проблема здесь в том, что я должен дважды щелкнуть, чтобы получить желаемые результаты. В CamperLeaderboard компонента handleSort функции, когда я console.log состояние не изменится, пока я не нажал дважды

Нажмите После

handleSort = (sort) => { 
    console.log(sort); // alltime 
    console.log(this.state.sort) //recent 
    this.setState({ sort: sort }); 
    console.log(this.state.sort) //recent 
    this.getData(); 
}; 

Нажмите дважды

handleSort = (sort) => { 
    console.log(sort); // alltime 
    console.log(this.state.sort) //alltime 
    this.setState({ sort: sort }); 
    console.log(this.state.sort) //alltime 
    this.getData(); 
}; 

Это CodePen preview и ниже полный код

/** 
    Table body component 
*/ 
class Table extends React.Component { 
    handleSort = (e, sort) => { 
    this.props.handleSort(sort); 
    }; 

    renderCampers = (key, count) => { 
    const camper = this.props.campers[key]; 
    return(
     <tr key={key}> 
     <td>{count}</td> 
     <td> 
      <a href={`https://www.freecodecamp.com/${camper.username}`} target='_blank'> 
      <img src={camper.img} /> 
      {camper.username} 
      </a> 
     </td> 
     <td className='center'>{camper.recent}</td> 
     <td className='center'>{camper.alltime}</td> 
     </tr> 
    ) 
    }; 

    render() { 
    let count = 0; 
    return (
     <div> 
     <table> 
      <caption>Leaderboard</caption> 
      <tr> 
      <th>#</th> 
      <th>Camper Name</th> 
      <th onClick={(e) => this.handleSort(e, 'recent')}><a href='javascript:void(0)'>Points in the past 30 days</a></th> 
      <th onClick={(e) => this.handleSort(e, 'alltime')}><a href='javascript:void(0)'>All time points</a></th> 
      </tr> 
      {Object.keys(this.props.campers).map(key => { 
      count++; 
      return this.renderCampers(key, count); 
      })} 
     </table> 
     </div> 
    ); 
    } 
} 

/** 
    Container 
*/ 
class CamperLeaderboard extends React.Component { 
    state = { 
    campers: [], 
    sort: 'recent' 
    }; 

    getData() { 
    let url = `https://fcctop100.herokuapp.com/api/fccusers/top/${this.state.sort}` 
    const self = this; 
    axios.get(url) 
     .then(function (response) { 
     self.setState({ campers: response.data }); 
     //console.log(self.state.campers); 
     }) 
     .catch(function (error) { 
     console.log(error); 
     }); 
    } 

    componentWillMount() { 
    this.getData(); 
    } 

    handleSort = (sort) => { 
    this.setState({ sort: sort }); 
    this.getData(); 
    }; 

    render() { 
    return (
     <div> 
     <p>Click links in table header to sort</p> 
     <Table campers={this.state.campers} 
       handleSort={this.handleSort} /> 
     </div> 
    ); 
    } 
} 

ReactDOM.render(<CamperLeaderboard />, document.getElementById('app')); 

/* 
To get the top 100 campers for the last 30 days: https://fcctop100.herokuapp.com/api/fccusers/top/recent. 
To get the top 100 campers of all time: https://fcctop100.herokuapp.com/api/fccusers/top/alltime. 
*/ 
+0

показывает ли интерфейс сортировки иметь место только после того, как во второй раз? Ваш console.log в первом примере, который имеет место сразу после установки состояния, почти всегда не будет отображаться обновленным состоянием, потому что 'this.setState' является асинхронным, что означает, что он войдет в очередь событий и, в конечном итоге, будет обновлен. consoleLog по-прежнему будет показывать предыдущее состояние, потому что его действие до фактического состояния было обновлено. Но если ваш пользовательский интерфейс не меняется после того, как вы установили, то произойдет еще кое-что. – finalfreq

+0

Да, пользовательский интерфейс показывает сортировку только после второго раза, когда я нажимаю в любом из заголовков – esausilva

ответ

2

Я считаю, что объяснение finalfreq верное, и вот как это исправить.

Update handleSort метод класса CamperLeaderboard как это:

handleSort = (sort) => { 
    this.setState({ sort: sort }); 
    // You don't need to read sort from state. Just pass it :) 
    this.getData(sort); 
} 
+1

Звучит правильно, вы не можете ожидать, что 'setState' будет работать в одном и том же режиме, говорят, что' setState() не сразу мутирует это. но создает ожидающий переход состояния. Доступ к this.state после вызова этого метода может потенциально вернуть существующее значение. Нет никакой гарантии синхронной работы вызовов setState, и вызовы могут быть собраны для повышения производительности. 'Http://stackoverflow.com/questions/30782948/why-calling-react-setstate-method-doesnt-mutate-the-state - немедленно –

+0

@R. Haluk Öngör, это для меня момент «духа», ваш ответ отлично работает. – esausilva

+1

@JuanMendes читает ваш связанный вопрос, я также могу это сделать и отлично работает 'this.setState ({sort},() => this.getData (this.state.sort));' – esausilva

Смежные вопросы