无法更新this.state.mostVoted

时间:2018-10-14 21:16:35

标签: reactjs

class App extends React.Component {
  constructor(props) {
      super(props)
      this.state = {
          selected: 0,
          votes: [0, 0, 0, 0, 0, 0],
          mostVoted: 0
      }
  }

  updateMostVoted = () => {
      let index = this.state.mostVoted
      const votes = this.state.votes
      for (let i = 0; i < votes.length; i++) {
          if (votes[i] > votes[index]) {
              index = i
          }
      }
      this.setState((prevState) => ({
          mostVoted: index
      }))
      console.log(index)
  }
}

2 个答案:

答案 0 :(得分:2)

首先。 setState是异步的,因此当您console.log时,需要在此setState之后执行功能。像这样:

this.setState(
  {
    mostVoted: index
  },
  () => {
    console.log(this.state.mostVoted);
  }
);

也许您可以给我们更多有关您想做的事情的信息,因为您的票数数组为零,而mostVoted也为零。

是的,我们需要更多信息。

答案 1 :(得分:0)

有关使用Array.prototype.reduce()updateMostVoted解决方案,请参见下文

请注意,使用setState的更新程序功能形式的目的是在执行计算时直接引用state,而不是通过this.state进行引用,这可能会导致错误(概述于文档)。

// Generate Array.
const generateArray = () => Array.from({length: 10}, () => Math.floor(Math.random() * 1000))

// Application.
class Application extends React.Component {
  
  // State.
  state = {
    mostVoted: false,
    selected: 0,
    votes: generateArray()
  }
  
  // Render.
  render() {
    const {mostVoted, votes} = this.state
    return (
      <React.Fragment>
        <div>Votes: {votes.join(', ')}</div>
        <br/>
        Most Voted 
        <div>Index: {mostVoted}</div>
        <div>Votes: {votes[mostVoted]}</div>
        <br/>
        <button onClick={this.generateVotes}>Generate Votes</button>
        <button onClick={this.updateMostVoted}>Update Most Voted</button>
      </React.Fragment>
    )
  }
  
  // Did Mount.
  componentDidMount() {
    this.updateMostVoted()
  }
  
  // Generate Votes Array.
  generateVotes = () => this.setState({mostVoted: false, votes: generateArray()})
  
  // Update Most Voted.
  updateMostVoted = () => this.setState(state => {
    const {votes} = this.state
    const {mostVoted} = votes.reduce((acc, x, i) => {
      if (x >= acc.value) return {mostVoted: i, value: x}
      return acc
    }, {mostVoted: 0, value: 0})
    return {mostVoted, votes}
  })
  
}

// Mount.
ReactDOM.render(<Application/>, document.getElementById('root'))
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>