Javascript ReactJS:setState后未捕获的范围错误
我正在尝试使用ReactJS和Flux创建一个简单的绘图应用程序。然而,我遇到了一个bug[UncaughtRangeError:超过了最大调用堆栈大小](更具体地说,这是一个ReactJS问题),我已经尝试了一段时间。它发生在我试图在组件中执行setState()时。下面是我的代码的一部分,以更好地说明我的问题 DrawingCanvas.react.jsJavascript ReactJS:setState后未捕获的范围错误,javascript,canvas,reactjs,reactjs-flux,Javascript,Canvas,Reactjs,Reactjs Flux,我正在尝试使用ReactJS和Flux创建一个简单的绘图应用程序。然而,我遇到了一个bug[UncaughtRangeError:超过了最大调用堆栈大小](更具体地说,这是一个ReactJS问题),我已经尝试了一段时间。它发生在我试图在组件中执行setState()时。下面是我的代码的一部分,以更好地说明我的问题 DrawingCanvas.react.js var React = require('react'); var MouseInteractionsMixin = re
var React = require('react');
var MouseInteractionsMixin = require('../utils/MouseInteractionsMixin');
var StrokeActionCreators = require('../actions/StrokeActionCreators');
var StrokeStore = require('../stores/StrokeStore');
function getStateFromStores() {
return {
currentStroke: StrokeStore.getCurrentStroke()
};
}
var DrawingCanvas = React.createClass({
mixins: [MouseInteractionsMixin],
styles: {
canvas: {
border: '1px solid black'
}
},
getInitialState: function() {
return getStateFromStores();
},
componentWillMount: function() {
StrokeStore.addChangeListener(this._update);
},
componentDidMount: function() {
this._onChange();
},
componentDidUpdate: function() {
this._onChange();
},
_onChange: function() {
if(this.state.dragging) {
StrokeActionCreators.beginStroke(this.state.mouse.point);
} else {
if(this.state.mouse.event == 'mouseup') {
StrokeActionCreators.endStroke(this.state.currentStroke);
}
}
},
_update: function() {
this.setState(getStateFromStores()); // where the problem occurs
context = this.getDOMNode().getContext('2d');
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
this._draw(context);
},
_draw: function(context) {
context.strokeStyle = '#000000';
context.lineJoin = 'round';
context.lineWidth = 5;
// Draw current stroke (incompleted)
for(var index = 1; index < this.state.currentStroke.points.length; index++) {
context.beginPath();
context.moveTo(this.state.currentStroke.points[index - 1].x, this.state.currentStroke.points[index - 1].y);
context.lineTo(this.state.currentStroke.points[index].x, this.state.currentStroke.points[index].y);
context.closePath();
context.stroke();
}
/*// Draw the other completed strokes
for(var strokeIndex = 0; strokeIndex < this.state.strokes.length; strokeIndex++) {
var stroke = this.state.strokes[strokeIndex];
for(var currentPointIndex = 1; currentPointIndex < stroke.points.length; currentPointIndex++) {
var previousPointIndex = currentPointIndex - 1;
context.beginPath();
context.moveTo(stroke.points[previousPointIndex].x, stroke.points[previousPointIndex].y);
context.lineTo(stroke.points[currentPointIndex].x, stroke.points[currentPointIndex].y);
context.closePath();
context.stroke();
}
}*/
},
render: function() {
return (
<canvas style={this.styles.canvas} width={this.props.width} height={this.props.height} />
);
}
});
module.exports = DrawingCanvas;
var AppDispatcher = require('../dispatchers/AppDispatcher');
var AppConstants = require('../constants/AppConstants');
var EventEmitter = require('events').EventEmitter;
var assign = require('object-assign');
var ActionTypes = AppConstants.ActionTypes;
var CHANGE_EVENT = 'change';
var _currentStroke = {
// Points array contains point objects with x and y variables
points: []
};
// Strokes array contains stroke objects with similar structure to currentStroke
var _strokes = [];
function _addPointToCurrentStroke(point) {
_currentStroke.points.push(point);
}
function _addStrokeToStrokes(stroke) {
_strokes.push(stroke);
}
function _clearCurrentStroke() {
_currentStroke = {
points: []
};
}
var StrokeStore = assign({}, EventEmitter.prototype, {
emitChange: function() {
this.emit(CHANGE_EVENT);
},
/**
* @param {function} callback
*/
addChangeListener: function(callback) {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function(callback) {
this.removeListener(CHANGE_EVENT, callback);
},
getCurrentStroke: function() {
return _currentStroke;
},
getStrokes: function() {
return _strokes;
}
});
AppDispatcher.register(function(payload) {
var action = payload.action;
switch(action.type) {
case ActionTypes.BEGIN_STROKE:
_addPointToCurrentStroke(action.point);
break;
case ActionTypes.END_STROKE:
_addStrokeToStrokes(action.stroke);
_clearCurrentStroke();
break;
default:
}
StrokeStore.emitChange();
});
module.exports = StrokeStore;
感谢您的帮助,谢谢 从StrokeStore或一个正在工作的JSFIDLE中添加代码片段真的很有帮助…@SaphuA编辑并添加了我的StrokeStore,谢谢!当错误发生时,调用堆栈中有什么
setState
也是异步的,因此它不一定是点管理和实时反馈的最佳匹配,特别是当它涉及到在画布上绘制时。此外,当画布被保留时,不需要不断地重新绘制它。@WiredPairie不确定我是否做对了,但它在Chrome上的调用堆栈中显示了(匿名函数)(extensions::messaging:182)。如果不需要重新绘制,那么有什么更好的方法?我的目标是能够将存储中的笔划数据与画布组件分离。我的问题是为什么要使用React状态系统来控制绘图和更新?您可以在React类中只包含本地字段。如果需要,您仍然可以使用存储,但对于实时绘图、更新,不要依赖于异步。