[英]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.