0

我正在使用Material UIwithreact-beautiful-dnd创建一个非常简单的Grid列布局,其中包含可以重新排序的元素。但是,我遇到了难以解释的元素间距问题,所以我只给你看一个 gif:

重新排序

我不确定这个问题可能来自哪里,甚至不知道该怎么称呼它。在内部, 的spacing属性Grid是使用 实现的padding,我什至找不到任何关于为什么它不能与拖放系统一起使用的信息。这是代码的主要部分:

import { makeStyles } from "@material-ui/core";
import { Grid, Paper } from "@material-ui/core";
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
import { produce } from "immer";

function ReorderQuestion(props) {
  const [items, setItems] = useState(props.items);
  const classes = useStyles();

  function onDragEnd({ source, destination }) {
    if (!destination) {
      return;
    }

    if (
      destination.droppableId === source.droppableId &&
      destination.index === source.index
    ) {
      return;
    }

    setItems(
      produce(draft => {
        draft.splice(destination.index, 0, draft.splice(source.index, 1)[0]);
      })
    );
  }

  return (
    <DragDropContext onDragEnd={onDragEnd}>
      <Droppable droppableId="reorderQuestion" direction="horizontal">
        {provided => (
          <div {...provided.droppableProps} ref={provided.innerRef}>
            <Grid spacing={3} container direction="row">
              {items.map((imageSrc, index) => (
                <Grid item key={imageSrc}>
                  <Draggable draggableId={imageSrc} index={index}>
                    {(provided, snapshot) => (
                      <Paper
                        innerRef={provided.innerRef}
                        {...provided.draggableProps}
                        {...provided.dragHandleProps}
                        elevation={
                          snapshot.isDragging && !snapshot.isDropAnimating
                            ? 5
                            : 2
                        }
                        className={classes.option}
                      >
                        <img src={imageSrc} alt="Hiking" />
                      </Paper>
                    )}
                  </Draggable>
                </Grid>
              ))}
              {provided.placeholder}
            </Grid>
          </div>
        )}
      </Droppable>
    </DragDropContext>
  );
}

const useStyles = makeStyles(theme => ({
  option: {
    padding: theme.spacing(2)
  }
}));
4

1 回答 1

3

感谢 Reactiflux Discord 上的@mal#8537,找到了解决方案。

问题是它innerRef被提供给Paper组件,它实际上不包含间距 - 即,它不使用边距。它的Grid item父组件 , 使用 padding 来实现间距,因此它必须被移动到内部Draggable并提供innerRef(和draggableProps)才能正确拖动间距。

我只是items.map用这个替换了内部:

<Draggable draggableId={imageSrc} index={index} key={imageSrc}>
    {(provided, snapshot) => (
        <Grid item
            innerRef={provided.innerRef} // PROVIDE REF HERE, TO GRID
            {...provided.draggableProps}>
          <Paper
            {...provided.dragHandleProps}
            elevation={
              snapshot.isDragging && !snapshot.isDropAnimating
                ? 5
                : 2
            }
            className={classes.option}
          >
            <img src={imageSrc} alt="Hiking" />
          </Paper>
        </Grid>
    )}
</Draggable>
于 2020-06-25T03:09:49.440 回答