尝试从fabric.js事件处理程序调度操作会导致“Reducers可能不会调度操作”。

时间:2016-08-05 12:39:28

标签: javascript reactjs redux fabricjs react-redux

我正在使用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认为我试图这样做。

从事件处理程序中,我触发另一个调度操作的事件。 我做错了什么?

修订版


在定义了store和fabric之后,两个处理程序都在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 
    })
})

这是我的reducers.js文件http://pastebin.com/SFHZ9jVr

1 个答案:

答案 0 :(得分:1)

您的处理ADD_TEXT操作reducers.js文件:

const newTextObj = new fabric.Text(action.payload.text)
fabricCanvas.add(newTextObj)
fabricCanvas.fire('object:selected')
return {
    ...state,
    objects: [
        ...state.objects,
        newTextObj
    ]
}

你不应该在减速器中发射任何事件。

在发送ADD_TEXT操作之前/之后解雇他们:

// 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中触发'object:selected'事件,从而产生操作调度。