我是新的反应,所以我可能不理解正确的思维概念。
我想做自动更新数据组件,可以我挂载和卸载。
这是一个错误,当我卸载然后挂载组件时:
警告:setState(.):只能更新挂载或安装组件。这通常意味着在未挂载的组件上调用setState()。这是禁止行动。请检查MeasurementsDataTable组件的代码。
这是密码:
var getDataInretval;
var listenersService = new ListenersService();
var Data = [{}];
function ListenersService(){
var listeners = {};
this.addListener = function(callback){
var id;
if(typeof callback === 'function'){
id = Math.random().toString(36).slice(2);
listeners[id] = callback;
}
return id;
}
this.removeListener = function( id){
if(listeners[id]){
delete listeners[id];
return true;
}
return false;
}
this.notifyListeners = function(data){
for (var id in listeners) {
if(listeners.hasOwnProperty(id)){
listeners[id](data);
}
}
}
}
var dataSevice = new DataMeasurementService(ListenersService);
function DataMeasurementService(ListenersService){
Data.push( new MeasurementDataForTable("header1", "th", "Phase measurements", "L1", "L2", "L3", "Total", "Others") );
var self = this;
//var listenersService = new ListenersService();
this.addListener = listenersService.addListener;
this.removeListener = listenersService.removeListener;
this.getData = function(){
return Data;
}
$.ajax({
url: "BL/getMeasurementsData.php",
type: "GET",
dataType: "html",
async: false,
success: function(res) {
var parseData = parseMeasurementsData( res );
Data = createOriginData( parseData );
},
error: function(request, status, error) {
alert("error: " + request.responseText);
}
});
listenersService.notifyListeners(Data);
}
var ThElement = React.createClass({
render: function(){
return <th width={this.props.width}>{this.props.data}</th>;
}
});
var TdElement = React.createClass({
render: function(){
return <td>{this.props.data}</td>;
}
});
var MeasurementsDataTable = React.createClass({
getInitialState: function() {
return {
data: this.props.dataService.getData()
};
},
componentDidMount: function() {
getDataInretval = setInterval(function(){
$.ajax({
url: "BL/getMeasurementsData.php",
type: "GET",
dataType: "html",
async: false,
success: function(res) {
var parseData = parseMeasurementsData( res );
Data = createOriginData( parseData );
},
error: function(request, status, error) {
alert("error: " + request.responseText);
}
});
listenersService.notifyListeners(Data);
}, 1000);
},
componentWillMount: function () {
this.props.dataService.addListener(this.updateHandler);
},
componentWillUnmount: function () {
this.removeListener = listenersService.removeListener;
clearInterval(getDataInretval);
},
updateHandler: function(data) {
this.setState({
data: data
});
},
render: function() {
return (
<div>
<table>
{
this.state.data.map(function(item) {
if( item.element == "th" ){
return (
<thead><tr>
<ThElement width="280" data={item.description}/>
<ThElement width="150" data={item.L1}/>
<ThElement width="150" data={item.L2}/>
<ThElement width="150" data={item.L3}/>
<ThElement width="150" data={item.total}/>
<ThElement width="150" data={item.others}/>
</tr></thead>
)
}
else{
return (
<tr>
<TdElement data={item.description}/>
<TdElement data={item.L1}/>
<TdElement data={item.L2}/>
<TdElement data={item.L3}/>
<TdElement data={item.total}/>
<TdElement data={item.others}/>
</tr>
)
}
})
}
</table>
</div>
);
}
});
ReactDOM.render( <MeasurementsDataTable dataService={dataSevice} />, document.getElementById("tablePlaceHolder") );
发布于 2015-12-17 13:47:33
您必须确保组件没有继续侦听附加的事件侦听器,并试图在卸载后更新自己。
您需要在使用React时跟踪所有事件侦听器。如果事件侦听器中的数据导致组件更新,则必须将侦听器附加到生命周期方法componentWillMount(),并在componentWillUnmount()中分离所有侦听器。
侦听器可以是组件侦听并通过setState()方法自行更改的任何内容。它可以是来自套接字的数据、来自服务器的数据、关于窗口调整大小事件的数据、setInterval侦听器等。
发布于 2015-12-17 13:42:36
我相信问题出在你的componentWillMount上。
在挂载组件之前,请执行以下操作
在componentWillMount中添加侦听器
componentWillMount: function () {
this.props.dataService.addListener(this.updateHandler);
},这意味着您运行这个函数。
DataMeasurementService(ListenersService)在执行该函数的最后,您将运行
listenersService.notifyListeners(Data);它依次运行您添加的任何侦听器,包括刚才添加的this.updateHandler,如下所示
updateHandler: function(data) {
this.setState({
data: data
});
},和威尔setState()。
这一切都发生在组件挂载之前的,因为所有这些都发生在componentWillMount中,Will是这里的关键字。换句话说,错误消息到底是怎么说的。
这通常意味着在未挂载的组件上调用setState()。
您应该添加任何可能在componentDidMount中更改组件状态的内容,这是在组件挂载之后发生的,以确保组件不会卡在循环中或尝试更新未安装的组件。
记住,两次呈现组件是非常好的。第一次,您安装它并呈现类似于Loading...的内容。然后在componentDidMount中,您可以执行任何api获取、添加事件侦听器和其他需要完成的操作。最后,用它的实际内容更新(setState())组件。
发布于 2015-12-17 14:40:33
实际上,您正在设置componentDidMount中的间隔,这是在场景后面进行的,并试图设置组件的卸载状态。
检查一下你的间隔是否被清除了?在您的componentWillUnmount中,还有一件事是尝试删除所有具有特定id或清除all的侦听器,
现在您没有清除,您没有传递任何id,所以我认为问题在于侦听器。
https://stackoverflow.com/questions/34335525
复制相似问题