Javascript 试图从fabric.js事件处理程序中分派操作会导致;减速机不得调度行动。”;

Javascript 试图从fabric.js事件处理程序中分派操作会导致;减速机不得调度行动。”;,javascript,reactjs,redux,fabricjs,react-redux,Javascript,Reactjs,Redux,Fabricjs,React Redux,我正在使用fabric.js和redux/react开发一个应用程序 简而言之,我想要的是当我在画布上添加一个对象时,它被选中并写入应用程序状态 这就是我现在所拥有的——当我点击画布上的一个对象时,“object:selected”事件 被激发,我将调度操作以将选定对象保存到我的应用程序状态 fabricCanvas.on('object:selected', function(options) { store.dispatch({ type: 'SET_SELECTED

我正在使用fabric.js和redux/react开发一个应用程序

简而言之,我想要的是当我在画布上添加一个对象时,它被选中并写入应用程序状态

这就是我现在所拥有的——当我点击画布上的一个对象时,“object:selected”事件 被激发,我将调度操作以将选定对象保存到我的应用程序状态

fabricCanvas.on('object:selected', function(options) {
    store.dispatch({ 
       type: 'SET_SELECTED_OBJECT',
       object: options.target 
    })
})
它工作得很好,但当我尝试在将对象添加到画布时自动将其设置为选中时,乐趣就开始了

fabricCanvas.on('object:added', function(options) {
   fabricCanvas.setActiveObject(options.target) 
})
函数setActiveObject()激发“object:selected”,这是非常合乎逻辑的,我希望我的dispatch处理程序能够工作,但它却授予我

Uncaught Error: Reducers may not dispatch actions.
我知道有一个限制,以派遣行动,从减少,但我不明白为什么Redux认为我试图

从事件处理程序中,我触发另一个事件,该事件分派一个操作。 我做错了什么

更新:
这两个处理程序都是在index.js中定义的,就在存储和结构定义之后

import 'babel-polyfill';
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import rootReducer from './reducers'
import App from './components/App'

import { clearSelectedObject, setSelectedObject, addObject } from './actions'
import initialState from './initialState.js'



let store = createStore(rootReducer, initialState, window.devToolsExtension && window.devToolsExtension())


render(
    <div id="ocdc-holder">
        <Provider store={store}>
            <App />
        </Provider> 
    </div>,
    document.getElementById('root')
)

const fabricCanvas = new fabric.Canvas('canvas-lower')

fabricCanvas.on('object:added', function(options) {
   fabricCanvas.setActiveObject(options.target) 
})

fabricCanvas.on('object:selected', function(options) {
    store.dispatch({ 
       type: 'SET_SELECTED_OBJECT',
       object: options.target 
    })
})
导入“babel polyfill”;
从“React”导入React
从'react dom'导入{render}
从“react redux”导入{Provider}
从“redux”导入{createStore}
从“./reducers”导入rootReducer
从“./components/App”导入应用程序
从“/actions”导入{clearSelectedObject、setSelectedObject、addObject}
从“./initialState.js”导入initialState
let store=createStore(rootReducer,initialState,window.devToolsExtension&&window.devToolsExtension())
渲染(

您的处理
添加文本
操作
reducers.js
文件:

const newTextObj = new fabric.Text(action.payload.text)
fabricCanvas.add(newTextObj)
fabricCanvas.fire('object:selected')
return {
    ...state,
    objects: [
        ...state.objects,
        newTextObj
    ]
}
你不应该在减速器中触发任何事件

在分派之前/之后激发它们
添加文本
操作:

// Somewhere in component, or where you are dispatching `ADD_TEXT` action.
const newTextObj = new fabric.Text(action.payload.text)
fabricCanvas.add(newTextObj)
fabricCanvas.fire('object:selected')
reducer应该没有副作用。reducer应该做的一切,就是使用以前的状态和已调度的操作返回新的状态


你得到了这个错误,因为你在reducer中触发了
'object:selected'
事件,这会产生动作分派。

你在哪里定义这两个事件处理程序?另外,你能在pastebin.com上提供所有的reducer代码吗?更新了这个问题。哦,对不起,我复制了reducer.js的错误版本。实际上没有这个line触发事件。@MaxHladkiy,但您仍在创建
newtextrabj
并将其添加到画布中。此代码也应该从reducer中删除。因此,错误是由setActiveObject()函数引起的,该函数本身触发“objects:selected”事件。我不明白为什么(无论如何,还原程序不是实例化对象的地方。请尝试从还原程序中删除所有执行副作用的代码。我的意思是,还原程序应该做的一切都是返回新状态,仅此而已。