尝试从 fabric.js 事件处理程序分派操作会导致 "Reducers may not dispatch actions."
Trying to dispatch an action from the fabric.js event handler causes "Reducers may not dispatch actions."
我正在使用 fabric.js 和 redux/react 开发应用程序。
很快,我想要的是当我在 canvas 上添加一个对象时,它被选中并写入应用程序状态。
这是我现在所拥有的 - 当我在 canvas 事件上单击一个对象时 "object:selected"
被触发,我分派操作以将所选对象保存到我的应用程序状态中。
fabricCanvas.on('object:selected', function(options) {
store.dispatch({
type: 'SET_SELECTED_OBJECT',
object: options.target
})
})
它工作得很好,但是当我尝试将对象添加到 canvas 时自动将其设置为选中时,乐趣就开始了。
fabricCanvas.on('object:added', function(options) {
fabricCanvas.setActiveObject(options.target)
})
函数 setActiveObject() 触发了 "object:selected",这是非常合乎逻辑的,我希望我的处理程序可以派发,但它却授予我
Uncaught Error: Reducers may not dispatch actions.
我知道从 reducer 派发动作有限制,但我不明白为什么 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
})
})
这是我的 reducers.js 文件 http://pastebin.com/SFHZ9jVr
您的处理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
]
}
你不应该在 reducer 中触发任何事件。
解雇他们 before/after 调度 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')
Reducers 应该没有副作用。 reducer 应该做的一切,就是 return 新状态,使用以前的状态和分派的动作。
您收到此错误,因为您在 reducer 中触发了 'object:selected'
事件,它会产生动作调度。
我正在使用 fabric.js 和 redux/react 开发应用程序。
很快,我想要的是当我在 canvas 上添加一个对象时,它被选中并写入应用程序状态。
这是我现在所拥有的 - 当我在 canvas 事件上单击一个对象时 "object:selected" 被触发,我分派操作以将所选对象保存到我的应用程序状态中。
fabricCanvas.on('object:selected', function(options) {
store.dispatch({
type: 'SET_SELECTED_OBJECT',
object: options.target
})
})
它工作得很好,但是当我尝试将对象添加到 canvas 时自动将其设置为选中时,乐趣就开始了。
fabricCanvas.on('object:added', function(options) {
fabricCanvas.setActiveObject(options.target)
})
函数 setActiveObject() 触发了 "object:selected",这是非常合乎逻辑的,我希望我的处理程序可以派发,但它却授予我
Uncaught Error: Reducers may not dispatch actions.
我知道从 reducer 派发动作有限制,但我不明白为什么 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
})
})
这是我的 reducers.js 文件 http://pastebin.com/SFHZ9jVr
您的处理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
]
}
你不应该在 reducer 中触发任何事件。
解雇他们 before/after 调度 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')
Reducers 应该没有副作用。 reducer 应该做的一切,就是 return 新状态,使用以前的状态和分派的动作。
您收到此错误,因为您在 reducer 中触发了 'object:selected'
事件,它会产生动作调度。