简体   繁体   中英

Unable to re-render/refresh a component with setState or forceUpdate

I'm using React to build a web application that will display a different quote every time the user clicks a button. I've been hunting for a way to get my component QuoteGenerator to re-render/refresh on a button-click, and I've tried all the possibilities presented in this article with no success.

class QuoteGenerator extends React.Component {
  constructor(props) {
        super(props);
        this.state = {num: Math.floor(Math.random() * quotes.length)};
    }

  render() {
    return(
      <div class="quoteBox">
        <div class="quote">
          "{quotes[this.state.num][0]}"<br/>
        </div>
        <button class="button btn" onClick={this.forceUpdate}>New Quote</button>
      </div>
    );
  }
}

Even creating a separate function that runs this.forceUpdate() or this.setState() and calling that function with onClick hasn't worked; I think I must be implementing something wrong. Does anyone see where my error might be?

Looks like you only pick the quote once. The constructor will run when the component is instantiated but will not run on every click.

Add a method:

nextQuote() {
  this.setState({
    num: Math.floor(Math.random() * quotes.length),
  });
}

and call it from your onClick (be careful with this ).

Note: You don't normally need to call forceUpdate on a react component. Just call setState , tell React what changed and the update will happen on its own. From the docs:

Normally you should try to avoid all uses of forceUpdate() and only read from this.props and this.state in render() .

You should use setState if you want to render the component instead of using this.forceUpdate() .

You can refer ReactJS official documentation to verify the same because it is not good practice.

https://reactjs.org/docs/react-component.html#forceupdate

You can write custom method to setState every time you click the button. Also not sure where quotes value is coming from :)

Hopefully this is useful.

randomQuote = () => {
  this.setState({
    num: Math.floor(Math.random() * this.state.quotes.length)
  })
}

Not sure onClick={this.forceUpdate} would have proper context to do its job. I'd wrap it in an inline function passing context (es6) or bind this context to it in the constructor

<button class="button btn" onClick={() => this.forceUpdate()}>New Quote</button>

Furthermore, global quotes object seems a bad pattern, you should give that to your component props

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM