钩子-Hooks
目录
- 什么钩子可用?
- 钩子的第二个参数:
provided: HookProvided onDragStart(可选的)onDragUpdate(可选的)onDragEnd(需要)- 次要:
onBeforeDragStart - 钩子什么时候调用?
- 同步重新排序
- 在拖动过程中阻止更新
onDragStart和onDragEnd配对
DragDropContext > Hooks
钩子是顶级应用程序事件,您可以使用它来执行自己的状态更新 以及 制作屏幕阅读器公告.
有关控制屏幕阅读器的更多信息,请参阅我们的屏幕阅读器指南
什么钩子可用?
主要
onDragStart:拖动已经开始了onDragUpdate:在拖动过程中发生了一些变化onDragEnd(必要):拖拽已结束。此钩子的责任是同步应用由拖动导致的更改
次要
通常你不需要使用
onBeforeDragStart,它与其他钩子函数签名略有不同
onBeforeDragStart\:就在onDragStart之前,并且可以用于进行表格 重新排序的尺寸锁定.
钩子的第二个参数:provided: HookProvided
type HookProvided = {|announce: Announce|};type Announce = (message: string) => void;
所有钩子(除了onBeforeDragStart)提供了第二个参数:HookProvided。该对象有一个属性:announce。此函数用于同步发布屏幕阅读器的消息.如果您不使用此函数,我们将宣布默认的英语消息。我们创造了一个屏幕阅读器使用指南,如果您有兴趣自己控制屏幕阅读器消息,并支持国际化,我们建议使用。如果你正在使用announce,请必须同步调用.
onDragStart(可选的)
type OnDragStartHook = (start: DragStart, provided: HookProvided) => mixed;
onDragStart拖动开始时,会收到通知。这个钩子是可选的因此不需要提供。但强烈推荐您使用此函数来阻止拖动过程中对所有Draggable和Droppable组件的更新。(可看下面拖动期间阻止更新)
您将获得以下详细信息:
start: DragStart
type DragStart = {|draggableId: DraggableId,type: TypeId,source: DraggableLocation|};
start.draggableId:Draggable正在拖拽的 IDstart.type:Draggable正在拖拽的typestart.source: (droppableId和index) 拖动物在Droppable中一个开始的位置.
onDragStart类型信息
注意:返回类型是mixed,不使用返回值.
type OnDragStartHook = (start: DragStart, provided: HookProvided) => mixed;// supporting typestype DragStart = {|draggableId: DraggableId,type: TypeId,source: DraggableLocation|};type DraggableLocation = {|droppableId: DroppableId,// the position of the draggable within a droppableindex: number|};type Id = string;type DraggableId = Id;type DroppableId = Id;type TypeId = Id;
onDragUpdate(可选的)
type OnDragUpdateHook = (update: DragUpdate, provided: HookProvided) => mixed;
只要拖动过程中发生某些变化,就会调用该钩子. 可能的变化是:
- 已经改变
Draggable的位置 - 该
Draggable现在被不同Droppable覆盖 - 该
Draggable现在被没有Droppable覆盖
重要的是,你不要因为这个函数而做太多的工作,因为它会减慢拖动。而返回类型是mixed,不使用返回值.
update: DragUpdate
type DragUpdate = {|...DragStart,// may not have any destination (drag to nowhere)destination: ?DraggableLocation|};
update.draggableId: 现在正在拖动Draggable的IDupdate.type: 现在正在拖动Draggable的typeupdate.source: (droppableId和index) 拖动物在Droppable中开始的位置.update.destination: (droppableId和index) 拖动物在Droppable中现在的位置. 如果用户当前没有拖动任何内容,则该值可以为nullDroppable.
onDragEnd(需要)
这个函数是在应用程序生命周期中扮演着非常重要的角色. 这个功能必然导致同步重新排序列表Draggables
它提供了有关拖动的所有信息:
result: DropResult
type DropResult = {|...DragUpdate,reason: DropReason|};type DropReason = 'DROP' | 'CANCEL';
result.draggableId: 现在正在拖动Draggable的IDresult.type: 现在正在拖动Draggable的typeresult.source:Draggable开始所在的位置.result.destination:Draggable借宿所在的位置. 该destination将会null,如果用户在不放在Droppable.result.reason: 发生放下的原因. 这些信息可以帮助我们制作更有用的消息HookProvided>announce功能.
次要:onBeforeDragStart
这个钩子的用例是超级有限的
一旦我们获得了开始拖动所需的所有信息,我们就调用onBeforeDragStart函数。这是在我们更新调用之前的Draggable和Droppable组件的snapshot-快照。此时应用程序不处于拖动状态,因此更改props, 类似isDropDisabled,都将失。该onBeforeDragStart钩子 是对表格 重新排序的尺寸锁定的好方法.
- ✅ 可以对现有组件进行修改,以锁定其大小
- ❌ 无法删除或添加任何
Draggable要么Droppable - ❌ 无法修改任何
Draggable要么Droppable尺寸 - ❌ 还没有屏幕阅读器公告
OnBeforeDragStartHook类型信息
注意:而返回类型是mixed,不使用返回值.
// 没有第二哥 'provided' 参数type OnBeforeDragStartHook = (start: DragStart) => mixed;// 其他的 就像 OnDragStartHook
钩子什么时候调用?
阶段 1:准备(异步)
- 用户启动拖动
- 我们准备,并收集拖动所需的信息(异步)。如果拖拽在此阶段完成之前结束,则不会触发任何钩子.
阶段 2:发布(同步)
onBeforeDragStart被调用Draggable和Droppable组件使用 初次snapshot-快照值 更新onDragStart被调用
阶段 3:更新
- 用户移动拖动项目
Draggable和Droppable组件使用最新snapshot值更新onDragUpdate被调用
阶段 4:放下
- 用户放下了拖动项目
- 一旦放下动画完成了,
Draggable和Droppable组件通过剩下snapshot值更新 onDragEnd被调用
同步重新排序
因为这个 库 不能控制你的状态,所以你可以基于result: DropResult, 同步重新排列你的列表.
这是你需要做的
- 如果
destination是null: 全做完了! - 如果
source.droppableId等于destination.droppableId您需要从列表中删除该项目并将其插入到正确的位置. - 如果
source.droppableId不相等destination.droppableId,那么你需要删除来自source.droppableId列表的Draggable, 并将其添加到正确的位置destination.droppableId列表.
坚持重新排序
如果您需要将重新排序保留到远程数据存储区 - 在客户端上同步更新列表,并在后台触发请求以保持更改. 如果远程保存失败,则由您决定如何与用户通信并更新或不更新列表.
在拖动过程中阻止更新
高度建议: 用户拖动时阻止可能影响数量的任何状态更新Draggables和Droppable或其尺寸. 请监听onDragStart并阻止更新Draggables和Droppable直到你收到onDragEnd.
当用户开始拖动时,我们会拍摄适用的所有尺寸的快照Draggable和Droppable节点. 如果在拖动过程中这些变化我们不会知道.
你如何阻止更新?
取决于您如何管理数据,更新阻止会有所不同. 这可能是最好的例子解释:
假设您正在使用React组件状态来管理应用程序的状态. 您的应用程序状态与 您每隔三十秒轮询一次数据更新 的REST端点相关联. 在拖动过程中,您不应该应用任何可能会影响可见效果的服务器更新.
这可能意味着:
- 在拖动过程中停止服务器轮询
- 在拖动过程中忽略来自服务器调用的任何结果 (不要调用
this.setState在您的组件中使用新数据)
没有更新阻止会导致不好的时间
这里有一些糟糕的用户体验,如果你改变了事情,在拖动期间可能会发生:
- 如果增加节点数量,那么 库 将不知道它们,并且当用户期望它们时, 它们将不会移动.
- 如果您减少节点数量,那么列表中可能会出现空白和意外动作.
- 如果更改任何节点的维度,则可能导致更改的节点以及其他节点在不正确的时间移动.
- 如果您删除用户正在拖动的节点,则该拖动将立即结束
- 如果您更改拖动节点的尺寸,那么其他内容在正确的时间将不会移动.
onDragStart和onDragEnd配对
我们非常努力地确保每一个onDragStart事件与单一配对onDragEnd事件. 但是,在这种情况下可能会出现流氓情况. 如果发生这种情况 - 这是一个错误. 目前没有任何机制可以告诉 库 从外部取消当前的拖拽.
