[英]React event listener and remounting
您好,自上周以來我一直在學習React,我解決了一個問題,但是我試圖理解為什么它可以解決我的問題。
這是代碼示例:
export default class ExampleComponent extends Component{
constructor(...arg){
super(...arg);
this.goToNextPage = this.goToNextPage.bind(this);
this.state = { currentPage: 1,
chapterImages: []};
}
goToNextPage(){
this.setState({
...this.state,
currentPage: R.inc(this.state.currentPage)
});
}
render(){
return (<button onClick={this.goToNextPage}>next</button>)
}
}
我有類似的東西。 在我的真實代碼中,我正在進行ajax調用,這是我的組件被卸載並重新安裝的原因……最后,當我單擊按鈕時,出現以下錯誤:
Warning: setState(...): Can only update a mounted or mounting component.
This usually means you called setState() on an unmounted component.
This is a no-op.
但是如果我從構造函數中刪除這一行:
this.goToNextPage = this.goToNextPage.bind(this);
並將render方法中的行修改為此:
return (<button onClick={this.goToNextPage.bind(this)}>next</button>)
它的工作原理完美,但我不知道為什么會收到上述錯誤。
我走這條路是因為卸載組件時,它會在按鈕單擊偵聽器中保留對綁定方法“ goToNextPage”的引用。
如何通過將綁定保留在構造函數中來解決該問題?
這是我真正的代碼類:
export default class MangaChapter extends Component{
constructor(...arg){
super(...arg);
this._getPageId = R.prop('pageId');
this._getPages = R.prop('pages');
this._generatePageMenuItem = (pageId) => (<MenuItem key={pageId} value={pageId} primaryText={`${pageId}`} />);
this._pageToMenuItem = R.compose(this._generatePageMenuItem, this._getPageId);
this._getMangaPageMenuItems = R.compose(R.map(this._pageToMenuItem), this._getPages);
this._toImageNode = (chapterPage) => (<img src={chapterPage.url} style={{display: 'block', margin: '0 auto'}}/>)
this._preloadImage = (chapterPage) => new Image().src = chapterPage.url;
this._preloadImages = R.forEach(this._preloadImage);
this._getImagePage = R.compose(R.map(this._toImageNode), this._preloadImages, this._getPages);
this.state = { currentPage: 1, chapterImages: this._getImagePage(this.props.chapter) };
this.goToPreviousPage = this.goToPreviousPage.bind(this);
this.goToNextPage = this.goToNextPage.bind(this);
}
componentWillMount(){
this.props.getChapter(this.props.params.mangaId, this.props.params.chapterNum);
}
componentWillUnmount(){
console.log('UNMOUNT');
}
componentWillReceiveProps(nextProps){
const { chapter } = nextProps;
this.state = { currentPage: 1, chapterImages: this._getImagePage(chapter) };
}
handleChange(event, index, currentPage){
this.setState({currentPage});
};
goToPreviousPage(){
this.setState({
currentPage: R.dec(this.state.currentPage)
});
}
goToNextPage(){
this.setState({
currentPage: R.inc(this.state.currentPage)
});
}
displayPage(){
return this.state.chapterImages[R.dec(this.state.currentPage)]
}
componentDidMount(){
}
render(){
const { chapter, loading } = this.props;
const chapterName = chapter.name;
const chapterNum = this.props.params.chapterNum;
if(loading) return (<CircularProgress size={80} thickness={5} style={loadingStyle} />);
return (
<div>
<h2 style={{textAlign: 'center'}}>Chapter { chapterNum } : { chapterName } </h2>
<div>
{this.displayPage()}
</div>
<div>
<br/>
<Row style={{textAlign: 'center'}}>
<Col sm={4}>
<RaisedButton
label="Previous"
primary={true}
icon={<ChevronLeft />}
onClick={this.goToPreviousPage}
/>
</Col>
<Col sm={4}>
Page
<SelectField
value={""}
onChange={this.handleChange.bind(this)}
style={{width: '80px', display: 'inline-block'}}
value={this.state.currentPage}
>
{this._getMangaPageMenuItems(chapter)}
</SelectField>
of { chapter.pages.length }
</Col >
<Col sm={4}>
<RaisedButton
labelPosition="before"
label="Next"
primary={true}
icon={<ChevronRight />}
style = {{display: 'inline-block'}}
onClick={this.goToNextPage}
/>
</Col>
</Row>
</div>
</div>
);
}
}
問題在於構造函數中的這兩個方法:
this.goToPreviousPage = this.goToPreviousPage.bind(this);
this.goToNextPage = this.goToNextPage.bind(this);
如果我這樣做,如果我將這些方法放在這樣的componentDidMount方法中,則會收到類似上面的錯誤:
componentDidMount(){
this.goToPreviousPage = this.goToPreviousPage.bind(this);
this.goToNextPage = this.goToNextPage.bind(this);
}
它運作完美,你知道為什么嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.