无法在 React 组件中使用 setState
Unable to use setState in react component
我有以下代码,它不允许我在安装后设置状态。
这是代码
import React, { Component } from 'react';
import Messages from '../locale/en/Messages';
import '../styles/base.css';
class AlertService extends Component {
state = {
message: '',
classType: 'alert-info',
isMessageSet: false
}
Messages = new Messages();
componentDidMount = () => {
console.log('This has mounted'); // This is working
}
componentWillUnmount = () => {
console.log('Is this getting unounted ?'); // This is working, the component is not getting unmounted
}
setAlert = (key, type, isMessage, readMore) => {
let message = isMessage ? key : this.Messages[key];
let classType = 'alert-info';
if (type === 0) {
classType = 'alert-danger';
} else if (type === 1) {
classType = 'alert-success';
}
this.openMessage(message,classType);
}
openMessage = (message,classType) =>{
this.setState({
message: message,
classType: classType,
isMessageSet: true
});
}
closeMessage = () => {
this.setState({
message: '',
classType: 'info',
isMessageSet: false
});
}
render() {
let classes = this.state.classType + ' ' + 'alertBox';
return (this.state.isMessageSet ?
<div className={classes}>
<div className="col-md-11"> {this.state.message} </div>
<div className="col-md-1 closeAlert" onClick={this.closeMessage}> x </div>
</div>
: null
)
}
}
export default AlertService;
尝试从此组件外部调用函数 setAlert 时出现以下错误。
但是,如果我将 isMessageSet
属性 设置为 true
然后单击 X 并调用 closeAlert 方法,它工作正常。
componentDidMount 表示组件正在挂载而 componentWillUnmount 永远不会执行,我不确定这里有什么问题
错误信息
无法在尚未安装的组件上调用 setState。这是一个空操作,但它可能表示您的应用程序中存在错误。相反,直接分配给 this.state
或在 AlertService 组件中定义具有所需状态的 state = {};
class 属性。
setState
不应从组件外部调用。如果你想从外部改变状态,使用道具。
正如错误信息所说,组件没有被挂载。您可以通过将 <AlertService />
添加到布局来安装它。
如果我理解正确的话,你说你尝试从另一个组件调用 setAlert
,它不起作用,但是当你调用 closeMessage
时它按预期工作,但后来我注意到你调用了 closeMessage
在同一个组件中,它会按预期工作,如果你想在另一个组件中调用属于这个组件的函数,那么你需要将组件导入到这个组件中,然后将函数传递给它,这样你就可以调用组件中的函数。例如:
import AnotherComponent from '../AnotherComponenet'
<AnotherComponent setAlert={this.setAlert} />
正如您在其中一条评论中提到的,您在实例化 AlertService class 后试图调用 setAlert 函数,我建议您看看您是如何做到的。正确的方法是:
this.AlertService = React.render(React.createElement(AlertService), mountnode) //挂载组件
this.AlertService.setAlert() // 现在你可以调用函数
根据你的用例,你可以像上面那样做。
React 的问题是 child 组件的方法不能被 parent 组件调用。由于这些对 child 来说是私有的,因此应该由它们自己处理。作为 hack,虽然我们可以使用 refs 来调用 child 组件的方法,但这不是 refs 的推荐用例。这可能会导致您的应用程序出现错误。
按照@vijayst 的建议,实现目标的最佳方法是更改 parent 组件的警报状态(无论何时收到消息),并将其作为道具传递给 child .现在在 componentWillReceiveProps().
下更新 child 的状态
我有以下代码,它不允许我在安装后设置状态。
这是代码
import React, { Component } from 'react';
import Messages from '../locale/en/Messages';
import '../styles/base.css';
class AlertService extends Component {
state = {
message: '',
classType: 'alert-info',
isMessageSet: false
}
Messages = new Messages();
componentDidMount = () => {
console.log('This has mounted'); // This is working
}
componentWillUnmount = () => {
console.log('Is this getting unounted ?'); // This is working, the component is not getting unmounted
}
setAlert = (key, type, isMessage, readMore) => {
let message = isMessage ? key : this.Messages[key];
let classType = 'alert-info';
if (type === 0) {
classType = 'alert-danger';
} else if (type === 1) {
classType = 'alert-success';
}
this.openMessage(message,classType);
}
openMessage = (message,classType) =>{
this.setState({
message: message,
classType: classType,
isMessageSet: true
});
}
closeMessage = () => {
this.setState({
message: '',
classType: 'info',
isMessageSet: false
});
}
render() {
let classes = this.state.classType + ' ' + 'alertBox';
return (this.state.isMessageSet ?
<div className={classes}>
<div className="col-md-11"> {this.state.message} </div>
<div className="col-md-1 closeAlert" onClick={this.closeMessage}> x </div>
</div>
: null
)
}
}
export default AlertService;
尝试从此组件外部调用函数 setAlert 时出现以下错误。
但是,如果我将 isMessageSet
属性 设置为 true
然后单击 X 并调用 closeAlert 方法,它工作正常。
componentDidMount 表示组件正在挂载而 componentWillUnmount 永远不会执行,我不确定这里有什么问题
错误信息
无法在尚未安装的组件上调用 setState。这是一个空操作,但它可能表示您的应用程序中存在错误。相反,直接分配给 this.state
或在 AlertService 组件中定义具有所需状态的 state = {};
class 属性。
setState
不应从组件外部调用。如果你想从外部改变状态,使用道具。
正如错误信息所说,组件没有被挂载。您可以通过将 <AlertService />
添加到布局来安装它。
如果我理解正确的话,你说你尝试从另一个组件调用 setAlert
,它不起作用,但是当你调用 closeMessage
时它按预期工作,但后来我注意到你调用了 closeMessage
在同一个组件中,它会按预期工作,如果你想在另一个组件中调用属于这个组件的函数,那么你需要将组件导入到这个组件中,然后将函数传递给它,这样你就可以调用组件中的函数。例如:
import AnotherComponent from '../AnotherComponenet'
<AnotherComponent setAlert={this.setAlert} />
正如您在其中一条评论中提到的,您在实例化 AlertService class 后试图调用 setAlert 函数,我建议您看看您是如何做到的。正确的方法是:
this.AlertService = React.render(React.createElement(AlertService), mountnode) //挂载组件 this.AlertService.setAlert() // 现在你可以调用函数
根据你的用例,你可以像上面那样做。
React 的问题是 child 组件的方法不能被 parent 组件调用。由于这些对 child 来说是私有的,因此应该由它们自己处理。作为 hack,虽然我们可以使用 refs 来调用 child 组件的方法,但这不是 refs 的推荐用例。这可能会导致您的应用程序出现错误。
按照@vijayst 的建议,实现目标的最佳方法是更改 parent 组件的警报状态(无论何时收到消息),并将其作为道具传递给 child .现在在 componentWillReceiveProps().
下更新 child 的状态