reactjs 如何在使用react-beautiful-dnd删除元素后保持适当的间距?

busg9geu  于 2023-03-29  发布在  React
关注(0)|答案(2)|浏览(150)

我使用Material UIreact-beautiful-dnd来创建一个非常简单的Grid列布局,其中的元素可以重新排序。然而,我遇到了一个很难解释的元素之间的间距问题,所以我只给你看一个GIF:

我不知道这个问题是从哪里来的,甚至不知道该怎么称呼它。在内部,Gridspacing属性是使用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)
  }
}));
km0tfn4u

km0tfn4u1#

找到了解决方案,感谢Reactiflux Discord上的@mal#8537。
问题是innerRef被提供给了Paper组件,而Paper组件实际上并不包含间距--也就是说,它没有使用边距。Grid item,其父组件,使用填充来实现间距,因此,必须在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>
8hhllhi2

8hhllhi22#

我尝试了@naiveal提出的解决方案,但不幸的是,它对我不起作用。为了解决这个问题,我添加了一个额外的div,其高度等于可拖动元素中的边距高度,这解决了这个问题。虽然它可能不是最优雅的解决方案,但它对我来说很好。我希望这个解决方案对遇到类似问题的任何人都有帮助。

<Draggable draggableId={id} index={index}>
      {(provided) => (
        <div
          ref={provided.innerRef}
          {...provided.draggableProps}
          {...provided.dragHandleProps}
        >
          {/* The extra div */}
          <div style={{ height: "1rem" }} /> 
           .....
        </div>
      )}
   </Draggable>

相关问题