【发布时间】: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