钩子-Hooks

目录

DragDropContext > Hooks

钩子是顶级应用程序事件,您可以使用它来执行自己的状态更新 以及 制作屏幕阅读器公告.

有关控制屏幕阅读器的更多信息,请参阅我们的屏幕阅读器指南

什么钩子可用?

主要

  • onDragStart:拖动已经开始了
  • onDragUpdate:在拖动过程中发生了一些变化
  • onDragEnd (必要):拖拽已结束。此钩子的责任是同步应用由拖动导致的更改

次要

通常你不需要使用onBeforeDragStart,它与其他钩子函数签名略有不同

  • onBeforeDragStart\:就在onDragStart之前,并且可以用于进行表格 重新排序的尺寸锁定.

钩子的第二个参数:provided: HookProvided

  1. type HookProvided = {|
  2. announce: Announce
  3. |};
  4. type Announce = (message: string) => void;

所有钩子(除了onBeforeDragStart)提供了第二个参数:HookProvided。该对象有一个属性:announce。此函数用于同步发布屏幕阅读器的消息.如果您不使用此函数,我们将宣布默认的英语消息。我们创造了一个屏幕阅读器使用指南,如果您有兴趣自己控制屏幕阅读器消息,并支持国际化,我们建议使用。如果你正在使用announce,请必须同步调用.

onDragStart(可选的)

  1. type OnDragStartHook = (start: DragStart, provided: HookProvided) => mixed;

onDragStart拖动开始时,会收到通知。这个钩子是可选的因此不需要提供。但强烈推荐您使用此函数来阻止拖动过程中对所有DraggableDroppable组件的更新。(可看下面拖动期间阻止更新)

您将获得以下详细信息:

start: DragStart

  1. type DragStart = {|
  2. draggableId: DraggableId,
  3. type: TypeId,
  4. source: DraggableLocation
  5. |};
  • start.draggableId: Draggable正在拖拽的 ID
  • start.type:Draggable正在拖拽的type
  • start.source: (droppableIdindex) 拖动物在Droppable中一个开始的位置.

onDragStart类型信息

注意:返回类型是mixed,不使用返回值.

  1. type OnDragStartHook = (start: DragStart, provided: HookProvided) => mixed;
  2. // supporting types
  3. type DragStart = {|
  4. draggableId: DraggableId,
  5. type: TypeId,
  6. source: DraggableLocation
  7. |};
  8. type DraggableLocation = {|
  9. droppableId: DroppableId,
  10. // the position of the draggable within a droppable
  11. index: number
  12. |};
  13. type Id = string;
  14. type DraggableId = Id;
  15. type DroppableId = Id;
  16. type TypeId = Id;

onDragUpdate(可选的)

  1. type OnDragUpdateHook = (update: DragUpdate, provided: HookProvided) => mixed;

只要拖动过程中发生某些变化,就会调用该钩子. 可能的变化是:

  • 已经改变Draggable的位置
  • Draggable现在被不同Droppable覆盖
  • Draggable现在被没有Droppable覆盖

重要的是,你不要因为这个函数而做太多的工作,因为它会减慢拖动。而返回类型是mixed,不使用返回值.

update: DragUpdate

  1. type DragUpdate = {|
  2. ...DragStart,
  3. // may not have any destination (drag to nowhere)
  4. destination: ?DraggableLocation
  5. |};
  • update.draggableId: 现在正在拖动Draggable的ID
  • update.type: 现在正在拖动Draggabletype
  • update.source: (droppableIdindex) 拖动物在Droppable中开始的位置.
  • update.destination: (droppableIdindex) 拖动物在Droppable中现在的位置. 如果用户当前没有拖动任何内容,则该值可以为nullDroppable.

onDragEnd(需要)

这个函数是在应用程序生命周期中扮演着非常重要的角色. 这个功能必然导致同步重新排序列表Draggables

它提供了有关拖动的所有信息:

result: DropResult

  1. type DropResult = {|
  2. ...DragUpdate,
  3. reason: DropReason
  4. |};
  5. type DropReason = 'DROP' | 'CANCEL';
  • result.draggableId: 现在正在拖动Draggable的ID
  • result.type: 现在正在拖动Draggabletype
  • result.source: Draggable开始所在的位置.
  • result.destination: Draggable借宿所在的位置. 该destination将会null,如果用户在不放在Droppable.
  • result.reason: 发生放下的原因. 这些信息可以帮助我们制作更有用的消息HookProvided>announce功能.

次要:onBeforeDragStart

这个钩子的用例是超级有限的

一旦我们获得了开始拖动所需的所有信息,我们就调用onBeforeDragStart函数。这是在我们更新调用之前的DraggableDroppable组件的snapshot-快照。此时应用程序不处于拖动状态,因此更改props, 类似isDropDisabled,都将失。该onBeforeDragStart钩子 是对表格 重新排序的尺寸锁定的好方法.

  • ✅ 可以对现有组件进行修改,以锁定其大小
  • ❌ 无法删除或添加任何Draggable要么Droppable
  • ❌ 无法修改任何Draggable要么Droppable尺寸
  • ❌ 还没有屏幕阅读器公告

OnBeforeDragStartHook类型信息

注意:而返回类型是mixed,不使用返回值.

  1. // 没有第二哥 'provided' 参数
  2. type OnBeforeDragStartHook = (start: DragStart) => mixed;
  3. // 其他的 就像 OnDragStartHook

钩子什么时候调用?

阶段 1:准备(异步)

  • 用户启动拖动
  • 我们准备,并收集拖动所需的信息(异步)。如果拖拽在此阶段完成之前结束,则不会触发任何钩子.

阶段 2:发布(同步)

  • onBeforeDragStart被调用
  • DraggableDroppable组件使用 初次snapshot-快照值 更新
  • onDragStart被调用

阶段 3:更新

  • 用户移动拖动项目
  • DraggableDroppable组件使用最新snapshot值更新
  • onDragUpdate被调用

阶段 4:放下

  • 用户放下了拖动项目
  • 一旦放下动画完成了,DraggableDroppable组件通过剩下snapshot值更新
  • onDragEnd被调用

同步重新排序

因为这个 库 不能控制你的状态,所以你可以基于result: DropResult, 同步重新排列你的列表.

这是你需要做的

  • 如果destinationnull: 全做完了!
  • 如果source.droppableId等于destination.droppableId您需要从列表中删除该项目并将其插入到正确的位置.
  • 如果source.droppableId不相等destination.droppableId,那么你需要删除来自source.droppableId列表的Draggable, 并将其添加到正确的位置destination.droppableId列表.

坚持重新排序

如果您需要将重新排序保留到远程数据存储区 - 在客户端上同步更新列表,并在后台触发请求以保持更改. 如果远程保存失败,则由您决定如何与用户通信并更新或不更新列表.

在拖动过程中阻止更新

高度建议: 用户拖动时阻止可能影响数量的任何状态更新Draggables和Droppable或其尺寸. 请监听onDragStart并阻止更新Draggables和Droppable直到你收到onDragEnd.

当用户开始拖动时,我们会拍摄适用的所有尺寸的快照DraggableDroppable节点. 如果在拖动过程中这些变化我们不会知道.

你如何阻止更新?

取决于您如何管理数据,更新阻止会有所不同. 这可能是最好的例子解释:

假设您正在使用React组件状态来管理应用程序的状态. 您的应用程序状态与 您每隔三十秒轮询一次数据更新 的REST端点相关联. 在拖动过程中,您不应该应用任何可能会影响可见效果的服务器更新.

这可能意味着:

  • 在拖动过程中停止服务器轮询
  • 在拖动过程中忽略来自服务器调用的任何结果 (不要调用this.setState在您的组件中使用新数据)

没有更新阻止会导致不好的时间

这里有一些糟糕的用户体验,如果你改变了事情,在拖动期间可能会发生:

  • 如果增加节点数量,那么 库 将不知道它们,并且当用户期望它们时, 它们将不会移动.
  • 如果您减少节点数量,那么列表中可能会出现空白和意外动作.
  • 如果更改任何节点的维度,则可能导致更改的节点以及其他节点在不正确的时间移动.
  • 如果您删除用户正在拖动的节点,则该拖动将立即结束
  • 如果您更改拖动节点的尺寸,那么其他内容在正确的时间将不会移动.

onDragStartonDragEnd配对

我们非常努力地确保每一个onDragStart事件与单一配对onDragEnd事件. 但是,在这种情况下可能会出现流氓情况. 如果发生这种情况 - 这是一个错误. 目前没有任何机制可以告诉 库 从外部取消当前的拖拽.