【问题标题】:redux state gets -improperly- updated before reducers is called (w/ ReactDnD)在调用 reducer 之前,redux 状态被 - 不正确 - 更新(w/ ReactDnD)
【发布时间】:2020-11-08 12:03:17
【问题描述】:

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


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

我遇到的问题是重新排列图像后我的道具没有更新。我一直在调试减速器,并注意到状态在减速器有机会这样做之前以某种方式更新(这将触发 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

可拖动项目

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 })
}

【问题讨论】:

  • @T.J.Crowder 已更新为管理结果状态的父组件('collectionReducer' 控制 'state.items')
  • 对不起,我以为您的意思是如何使用 reducer 的更新状态(这是 App.js - 之前发布的)。 -only- reducer 使用 redux 的 'combineReducers' 调用(更新了 reducer 代码以包含它)并由 index.js 中的 store 管理(也添加了)

标签: javascript reactjs redux react-redux react-dnd


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-28
    • 2016-07-02
    • 2020-02-09
    • 2019-07-28
    • 2019-07-05
    • 2021-02-06
    • 2018-08-04
    • 1970-01-01
    相关资源
    最近更新 更多