我收到以下警告
“警告:setState(…):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了setState()。这是空操作。请检查ContactPage组件的代码。”
当我最初进入联系页面时,第一时间很好。然后,如果我离开页面并返回,则会引发警告。
联系人页面组件:
import React, { Component, PropTypes } from 'react'; import AppStore from '../../stores/AppStore'; import AppActions from '../../actions/AppActions'; import DataContent from './DataContent'; const title = 'Contact Us'; class ContactPage extends Component { constructor(props) { super(props); this.state = AppStore.getState(); AppActions.getData(); } static contextTypes = { onSetTitle: PropTypes.func.isRequired, }; componentWillMount() { this.context.onSetTitle(title); AppStore.listen(this.onChange.bind(this)); } componentWillUnmount() { AppStore.unlisten(this.onChange.bind(this)); } onChange(state) { this.setState(state); } renderData() { return this.state.data.map((data) => { return ( <DataContent key={data.id} data={data} /> ) }) } render() { return ( <div className={s.root}> <div className={s.container}> <h1>{title}</h1> <div> { this.renderData() } </div> </div> </div> ); } } export default ContactPage;
当我放入调试器时,在联系页面加载时,它会击中componentWillMount()。当我离开联系页面时,它会碰到componentWillUnmount()。当我导航回到页面时,它再次击中componentWillMount(),然后在击中onChange(state)函数时引发错误。
问题是先前组件实例的侦听器仍处于注册状态。并且由于不再挂载以前的实例,因此您会收到该错误。
.bind总是返回一个 新 函数。所以如果你这样做
.bind
AppStore.unlisten(this.onChange.bind(this));
那么您尝试删除一个不存在的侦听器(当然会失败)。它并 不会 删除您注册的监听器AppStore.listen(this.onChange.bind(this))
AppStore.listen(this.onChange.bind(this))
为了解决这个问题,您应该在构造函数中绑定 一次 处理程序:
this.onChange = this.onChange.bind(this);
然后使用AppStore.listen(this.onChange)和 AppStore.unlisten(this.onChange)。
AppStore.listen(this.onChange)
AppStore.unlisten(this.onChange)