React:调用setState/forceUpdate无法重渲染QuoteGenerator组件,求排查
嘿,我来帮你找出问题所在!你的代码里有两个关键问题导致按钮点击后组件没反应,咱们一步步解决:
首先,事件处理函数的this绑定问题:你直接把this.forceUpdate传给了按钮的onClick,但在JavaScript中,当你把类方法作为回调传递时,this的上下文会丢失——点击按钮时,this指向的是按钮元素本身,而不是你的QuoteGenerator组件实例,所以调用的根本不是组件的forceUpdate方法,自然不会触发重渲染。
其次,还有个小细节:React元素里的属性应该用className而不是class,因为class是JavaScript的关键字,React用className来对应HTML的class属性,虽然这个不影响功能,但这是规范写法。
另外,其实完全没必要用forceUpdate,React的设计理念就是通过更新状态来触发重渲染,咱们直接更新state里的num就好。
下面是修改后的完整代码:
class QuoteGenerator extends React.Component { constructor(props) { super(props); this.state = { num: Math.floor(Math.random() * quotes.length) }; // 关键:把handleNewQuote的this绑定到组件实例 this.handleNewQuote = this.handleNewQuote.bind(this); } handleNewQuote() { // 生成新的随机索引,更新state触发重渲染 this.setState({ num: Math.floor(Math.random() * quotes.length) }); } render() { return( <div className="quoteBox"> <div className="quote"> "{quotes[this.state.num][0]}"<br/> </div> <button className="button btn" onClick={this.handleNewQuote}>New Quote</button> </div> ); } }
如果不想在构造函数里绑定this,也可以用箭头函数作为类字段(需要支持ES7语法或者配置Babel),写法更简洁:
class QuoteGenerator extends React.Component { state = { num: Math.floor(Math.random() * quotes.length) }; // 箭头函数自动绑定this到组件实例 handleNewQuote = () => { this.setState({ num: Math.floor(Math.random() * quotes.length) }); }; render() { return( <div className="quoteBox"> <div className="quote"> "{quotes[this.state.num][0]}"<br/> </div> <button className="button btn" onClick={this.handleNewQuote}>New Quote</button> </div> ); } }
这样修改后,点击按钮时就会调用组件的handleNewQuote方法,更新state里的随机索引,组件就会自动重渲染,展示新的名言啦!
内容的提问来源于stack exchange,提问作者Kiliann
相关产品推荐
相关产品推荐

