我收到以下警告
“警告: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(状态)函数时抛出错误。
答案 0 :(得分:38)
问题是前一个组件实例的监听器仍然是已注册的。并且由于之前的实例已经不再安装,因此您会收到该错误。
.bind
始终返回新功能。所以,如果你这样做
AppStore.unlisten(this.onChange.bind(this));
然后你试图删除一个不存在的监听器(当然失败了)。它不删除您使用AppStore.listen(this.onChange.bind(this))
要解决此问题,您应该在构造函数中绑定处理程序一次:
this.onChange = this.onChange.bind(this);
然后使用AppStore.listen(this.onChange)
和AppStore.unlisten(this.onChange)
。
答案 1 :(得分:6)
在更改之前,将安装状态检查组件。
O(q)
我认为这会对你有所帮助。
答案 2 :(得分:0)
在你的情况下,在你的root div中添加一个ref并在调用setState之前检查ref值。
您的onChange
方法应如下所示:
onChange(state) {
this.refs.yourRef ? this.setState(state) : null;
}
答案 3 :(得分:-1)
我一直在努力解决这个问题。
为我解决的问题是@Felix Kling提出的做法,但也确保我的回调函数在组件的类中声明,否则你无法使用this
前缀,这显然是做什么的我的诀窍。
这是我的意思的一个例子:
合法,但不起作用
function onChange() {
this.setState({ MyState: newState })
}
class MyComponent extends React.Component {
constructor(props) {
super(props);
onChange = onChange.bind(this);
}
componentDidMount() {
window.addEventListener('resize', onChange);
}
componentWillUnmount() {
window.removeEventListener('resize', onChange);
}
render() { ... }
}
<强> 作品 强>
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
}
onChange() {
this.setState({ MyState: newState })
}
componentDidMount() {
window.addEventListener('resize', this.onChange);
}
componentWillUnmount() {
window.removeEventListener('resize', this.onChange);
}
render() { ... }
}
希望它可以帮助其他任何人面对这个问题。 :)