redux 状态在调用 reducers 之前得到-不正确的-更新(使用/ React DnD)

redux state gets -improperly- updated before reducers is called (w/ ReactDnD)

编辑:错误是一个独立的辅助函数,它正在改变状态(未显示在 post 中)。


我正在尝试使用 ReactDnD 通过拖放创建可排序的图像网格。我一直在关注本教程 1 并尝试使用 redux 而不是 React Context 来实现它。

我遇到的问题是在我重新排列图像后我的道具没有得到更新。我一直在调试 reducer 并注意到状态在 reducer 有机会更新之前以某种方式更新(这将触发 mapStateToProps 以更新的状态重新加载我的组件)。问题是我不知道为什么会这样。我有一种感觉,因为 ReactDnD 也在使用 Redux,所以它以某种方式导致了这个。

以下是不同的部分:

Index.js

export const store = createStore(reducers, applyMiddleware(thunk))

ReactDOM.render(
    <Provider store={store}>
        <DndProvider backend={HTML5Backend}>
            <App />
        </DndProvider>
    </Provider>,
    document.getElementById('root')
)

App.js(DroppableCell 和 DraggableItem 的父组件)

class App extends React.Component {
    componentDidMount() {
        this.props.loadCollection(imageArray)
    }

    render() {
        return (
            <div className='App'>
                <div className='grid'>
                    {this.props.items.map((item) => (
                        <DroppableCell
                            key={item.id}
                            id={item.id}
                            onMouseDrop={this.props.moveItem}
                        >
                            <DraggableItem src={item.src} alt={item.name} id={item.id} />
                        </DroppableCell>
                    ))}
                </div>
            </div>
        )
    }
}

const mapStateToProps = (state) => {
    return { items: state.items }
}

export default connect(mapStateToProps, {
    moveItem,
    loadCollection,
})(App)

DroppableCell(从父组件调用动作创建器)

import React from 'react'
import { useDrop } from 'react-dnd'

const DroppableCell = (props) => {
    const [, drop] = useDrop({
        accept: 'IMG',
        drop: (hoveredOverItem) => {
            console.log(hoveredOverItem)
            props.onMouseDrop(hoveredOverItem.id, props.id)
        },
    })

    return <div ref={drop}>{props.children}</div>
}

export default DroppableCell

DraggableItem

import React from 'react'
import { useDrag } from 'react-dnd'

const DraggableItem = (props) => {
    const [, drag] = useDrag({
        item: { id: props.id, type: 'IMG' },
    })

    return (
        <div className='image-container' ref={drag}>
            <img src={props.src} alt={props.name} />
        </div>
    )
}

export default DraggableItem

减速器

import { combineReducers } from 'redux'

const collectionReducer = (state = [], action) => {
    // state is already updated before the reducer has been run
    console.log('state:', state, 'action: ', action)

    switch (action.type) {
        case 'LOAD_ITEMS':
            return action.payload
        case 'MOVE_ITEM':
            return action.payload
        default:
            return state
    }
}

export default combineReducers({
    items: collectionReducer,
})

动作创作者

export const moveItem = (sourceId, destinationId) => (dispatch, getState) => {
    const itemArray = getState().items
    const sourceIndex = itemArray.findIndex((item) => item.id === sourceId)
    const destinationIndex = itemArray.findIndex(
        (item) => item.id === destinationId
    )

    const offset = destinationIndex - sourceIndex
    //rearrange the array
    const newItems = moveElement(itemArray, sourceIndex, offset)

    dispatch({ type: 'MOVE_ITEM', payload: newItems })
}

发现了错误 - 不幸的是在发布的代码之外,因为我认为它是一个简单的辅助函数。我意识到我正在使用 'splice' 方法重新排列 imageArray,因此改变了状态。