我正在使用react-beautiful-dnd(https://github.com/atlassian/react-beautiful-dnd)库在列之间移动项目。将项目拖到其他列后,我试图更新状态列。在endDrag函数中,我即将在设置状态之前注销column变量,并且此时它是正确的。因此,要么我没有正确设置状态,要么我没有从列组件中正确读取状态。我的控制台日志在OrderColumn组件中正在输出列的旧状态,所以这似乎告诉我我没有正确设置状态。
这是我设置初始状态的上下文文件:
import React, { createContext, useState } from 'react';
export const ScheduleContext = createContext();
export const ScheduleProvider = (props) => {
const orderData = [
['First', 'First Order'],
['Second', 'Second Order'],
['Third', 'Third Order'],
['Fourth', 'Fourth Order'],
['Fifth', 'Fifth Order']
];
const tempOrders = orderData.map(function(val, index) {
return {
id: index,
title: val[0] + ' Order',
desc: 'This order is for ' + val[1] + '.'
};
});
const orderIDs = tempOrders.map(function(val) {
return val.id;
});
const columnCount = 5;
const cols = [];
for (let i = 0; i < columnCount; i++) {
cols.push({
title: 'Line ' + i,
columnID: 'column-' + i,
orderIDs: i === 0 ? orderIDs : []
});
}
// eslint-disable-next-line no-unused-vars
const [orders, setOrders] = useState(tempOrders);
// eslint-disable-next-line no-unused-vars
const [columns, setColumns] = useState(cols);
const contextValue = { orders, setOrders, columns, setColumns };
return (
<ScheduleContext.Provider value={contextValue}>
{props.children}
</ScheduleContext.Provider>
);
};
接下来,这是我的SchedulePage,它是App.js下的顶级组件。
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { DragDropContext } from 'react-beautiful-dnd';
import OrderColumn from '../ordercolumn/OrderColumn';
import { ScheduleContext } from '../../schedule-context';
const Schedule = () => {
const { columns, setColumns } = useContext(ScheduleContext);
const onDragEnd = (result) => {
const { destination, source } = result;
if (!destination) {
return;
}
if (
destination.droppableId === source.droppableId &&
destination.index === source.index
) {
return;
}
const column = columns.find(
(col) => col.columnID === source.droppableId
);
const orderIDs = Array.from(column.orderIDs);
orderIDs.splice(source.index, 1);
const newColumn = {
...column,
orderIDs: orderIDs
};
const ind = columns.indexOf(column);
columns.splice(ind, 1, newColumn);
console.log(columns);
setColumns(columns);
};
const columnsArray = Object.values(columns);
return (
<DragDropContext onDragEnd={onDragEnd}>
<div className={'full-width'}>
<h1 className={'text-center'}>Schedule</h1>
<div className={'lines row no-gutters'}>
{columnsArray.map(function(val, index) {
return (
<OrderColumn
key={index}
title={val.title}
columnId={val.columnID}
orderIDs={val.orderIDs}
/>
);
})}
</div>
</div>
</DragDropContext>
);
};
Schedule.propTypes = {
orders: PropTypes.array
};
export default Schedule;
最后,位于SchedulePage下的OrderColumn页面:
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { Droppable } from 'react-beautiful-dnd';
import styled from 'styled-components';
import Order from '../order/Order';
import { Scrollbars } from 'react-custom-scrollbars';
import { ScheduleContext } from '../../schedule-context';
import '../../App.css';
const MyOrder = styled.div``;
const OrderColumn = (props) => {
const colId = props.columnId;
const orders = useContext(ScheduleContext).orders;
const orderIDs = useContext(ScheduleContext).columns.find(
(col) => col.columnID === colId
).orderIDs;
console.log('orderIDs: ');
console.log(orderIDs);
return (
<Droppable droppableId={colId}>
{(provided) => {
console.log('orderIDs: ');
console.log(orderIDs);
return (
<MyOrder
className={'col order-column'}
ref={provided.innerRef}
{...provided.droppableProps}
>
<Scrollbars
// This will activate auto hide
autoHide
// Hide delay in ms
autoHideTimeout={1000}
// Duration for hide animation in ms.
autoHideDuration={200}
>
<h3 className={'text-center title'}>{props.title}</h3>
<div className={'orders'}>
{orderIDs &&
orderIDs.map((orderID, index) => {
const order = orders.find(
(o) => o.id === orderID
);
return (
<Order
key={orderID}
order={order}
index={index}
/>
);
})}
</div>
</Scrollbars>
{provided.placeholder}
</MyOrder>
);
}}
</Droppable>
);
};
OrderColumn.propTypes = {
orders: PropTypes.array,
title: PropTypes.string.isRequired,
columnId: PropTypes.string.isRequired
};
export default OrderColumn;
想出了如何使我的整个应用程序在线进行测试/查看的方法,如果这对任何人都有帮助:https://codesandbox.io/s/smoosh-shape-g8zsp
答案 0 :(得分:1)
据我了解,您更改了列,然后将其保存到状态。您的问题是您只是在改变状态:
columns.splice(ind, 1, newColumn); // <-- mutation of columns array
console.log(columns);
setColumns(columns); // <-- noop as react compares references of the arrays
为防止出现此问题,您应该只先创建一个副本,然后进行修改并保存。然后,React将接受更改:
const adjustedColumns = columns.slice(); // or Array.from(columns)
adjustedColumns.splice(ind, 1, newColumn);
setColumns(adjustedColumns);