Javascript ReactJS:setState后未捕获的范围错误

Javascript 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

我正在尝试使用ReactJS和Flux创建一个简单的绘图应用程序。然而,我遇到了一个bug[UncaughtRangeError:超过了最大调用堆栈大小](更具体地说,这是一个ReactJS问题),我已经尝试了一段时间。它发生在我试图在组件中执行setState()时。下面是我的代码的一部分,以更好地说明我的问题

DrawingCanvas.react.js

    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类中只包含本地字段。如果需要,您仍然可以使用存储,但对于实时绘图、更新,不要依赖于异步。