React DnD基礎(chǔ)概念和整體架構(gòu)

React DnD 的英文是 Drag and Drop for React锦担。
React DnD 是 React 和 Redux 的核心作者 Dan Abramov 創(chuàng)造的一組 React 高階組件祈坠,基于數(shù)據(jù)而不是視圖開發(fā)的一套拖拽工具,主要使用typescript進(jìn)行開發(fā)。

基礎(chǔ)概念和使用示例可以參考:http://www.reibang.com/p/8a1e16d5519b官方tutorial畦贸。
作者基于HTML5提供了一個(gè)backend實(shí)現(xiàn)抢腐,相關(guān)api參考:HTML_Drag_and_Drop_API

React DnD 的基本概念

Manager

Manager是DnD中非常重要的角色模叙,內(nèi)部保存了store、monitor和backend鞋屈,Manager作為入口范咨,對(duì)外暴露三者,會(huì)訂閱store厂庇,并調(diào)用Backend的setup(負(fù)責(zé)注冊(cè)拖拽相關(guān)一系列的事件)或teardown(銷毀拖拽事件)渠啊。

Backends

React DnD 抽象了后端的概念,我們可以使用 HTML5 拖拽后端权旷,也可以自定義 touch替蛉、mouse 事件模擬的后端實(shí)現(xiàn),后端主要用來(lái)抹平瀏覽器差異,處理 DOM 事件躲查,同時(shí)把 DOM 事件轉(zhuǎn)換為 React DnD 內(nèi)部的 redux action它浅。主要注冊(cè)了拖拽相關(guān)的監(jiān)聽器,對(duì)外提供了dom(drag镣煮、preview和drop)注入方法姐霍。

Item

React DnD 基于數(shù)據(jù)驅(qū)動(dòng),當(dāng)拖放發(fā)生時(shí)典唇,它用一個(gè)數(shù)據(jù)對(duì)象來(lái)描述當(dāng)前的元素镊折,比如 { cardId: 25 }。

Type

類型是唯一標(biāo)識(shí)應(yīng)用程序中整個(gè)項(xiàng)目類別的字符串(或符號(hào))介衔,類似于 redux 里面的 actions types 枚舉常量恨胚。

Monitors

拖放操作都是有狀態(tài)的,React DnD 通過(guò) Monitor 來(lái)存儲(chǔ)這些狀態(tài)并且提供查詢炎咖。

Connectors

Backend 關(guān)注 DOM 事件与纽,組件關(guān)注拖放狀態(tài),connector 可以連接組件和 Backend 塘装,可以讓 Backend 獲取到 DOM急迂。

useDrag

用于將當(dāng)前組件用作拖動(dòng)源的鉤子。

import { useDrag } from 'react-dnd'

function DraggableComponent(props) {
 const [collectedProps, drag] = useDrag({
   item: { id, type }
 })
 return <div ref={drag}>...</div>
}

useDrop

使用當(dāng)前組件作為放置目標(biāo)的鉤子蹦肴。

 const [collectedProps, drop] = useDrop({
   accept
 })

 return <div ref={drop}>Drop Target</div>
}

架構(gòu)與源碼

概略圖
backend: HTML5Backend

詳細(xì)調(diào)度圖

上圖說(shuō)明:
一僚碎、DndProvider
根據(jù)createDragDropManager(backend, context)創(chuàng)建名為dragDropManager的單例,并通過(guò)React.createContext共享阴幌,包含有store勺阐、monitor和backend信息;
二矛双、useDrag
2.1渊抽、通過(guò)useDragSourceMonitor生成DragSourceMonitorImpl實(shí)例monitor
1、通過(guò)useDragDropManager方法(本質(zhì)就是React.useContext)獲取dragDropManager單例议忽;
2懒闷、通過(guò)DragSourceMonitorImpl(dragDropManager)生成實(shí)例,內(nèi)部維護(hù)了一些諸如canDrag栈幸、isDragging愤估、didDrop等常用操作,本質(zhì)是通過(guò)dragDropManager單例內(nèi)部的manager實(shí)現(xiàn)速址。
2.2玩焰、通過(guò)useDragSourceConnector生成SourceConnector實(shí)例connector
1、通過(guò)useDragDropManager獲取manager芍锚,再通過(guò)manager.getBackend()獲取backend昔园;
2蔓榄、通過(guò)SourceConnector(backend)生成connector,然后將DragSourceOptions默刚、dragPreviewOptions分別保存在connector.dragSourceOptions甥郑、connector.dragPreviewOptions,并通過(guò)connector.reconnect()重連羡棵;connector內(nèi)部維護(hù)了dragSourceRef、dragSourceNode嗅钻、dragPreviewRef和dragPreviewNode等數(shù)據(jù)皂冰,還會(huì)通過(guò)調(diào)用backend.connectDragSource和backend.connectDragPreview方法,將drag和preivew相關(guān)信息傳入backend养篓。
2.3秃流、通過(guò)useRegisteredDragSource(spec, monitor, connector)注冊(cè)DragSource
1、通過(guò)DragSourceImpl(spec, monitor, connector)生成DragSource實(shí)例handler柳弄,提供了beginDrag舶胀、canDrag、isDragging和endDrag方法碧注,四個(gè)方法基本是調(diào)用spec中配置的相應(yīng)方法嚣伐;
2、調(diào)用manger的registry將handler注冊(cè)到manager中(manager.getRegitry().addSource)萍丐,生成對(duì)應(yīng)的handlerId轩端,通過(guò)monitor和connector的receiveHandlerId方法注入到各自里面。
2.4逝变、通過(guò)useCollectedProps(spec.collect, monitor, connector)返回collect數(shù)據(jù)
通過(guò)monitor.subscribeToStateChange方法注冊(cè)監(jiān)聽方法updateCollected基茵,該方法會(huì)通過(guò)collect(monitor)獲取到最新的結(jié)果

2.5、dragRef通過(guò)useConnectDragSource(connector)返回dragRef
通過(guò)執(zhí)行connector.dragSource方法獲取最新的drag ref壳影,并reconnectDragSource拱层。
2.6、通過(guò)useConnectDragPreview(connector)返回dragPreview
類似2.5宴咧。
三根灯、useDrop
四、Backend(HTML5Backend)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末掺栅,一起剝皮案震驚了整個(gè)濱河市箱吕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柿冲,老刑警劉巖茬高,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異假抄,居然都是意外死亡怎栽,警方通過(guò)查閱死者的電腦和手機(jī)丽猬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)熏瞄,“玉大人脚祟,你說(shuō)我怎么就攤上這事∏恳” “怎么了由桌?”我有些...
    開封第一講書人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)邮丰。 經(jīng)常有香客問(wèn)我行您,道長(zhǎng),這世上最難降的妖魔是什么剪廉? 我笑而不...
    開封第一講書人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任娃循,我火速辦了婚禮,結(jié)果婚禮上斗蒋,老公的妹妹穿的比我還像新娘捌斧。我一直安慰自己,他們只是感情好泉沾,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開白布捞蚂。 她就那樣靜靜地躺著,像睡著了一般跷究。 火紅的嫁衣襯著肌膚如雪洞难。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評(píng)論 1 308
  • 那天揭朝,我揣著相機(jī)與錄音队贱,去河邊找鬼。 笑死潭袱,一個(gè)胖子當(dāng)著我的面吹牛柱嫌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播屯换,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼编丘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了彤悔?” 一聲冷哼從身側(cè)響起嘉抓,我...
    開封第一講書人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晕窑,沒(méi)想到半個(gè)月后抑片,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡杨赤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年敞斋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了截汪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡植捎,死狀恐怖衙解,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情焰枢,我是刑警寧澤蚓峦,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站济锄,受9級(jí)特大地震影響暑椰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拟淮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一干茉、第九天 我趴在偏房一處隱蔽的房頂上張望谴忧。 院中可真熱鬧很泊,春花似錦、人聲如沸沾谓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)均驶。三九已至昏兆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間妇穴,已是汗流浹背爬虱。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腾它,地道東北人跑筝。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像瞒滴,于是被迫代替她去往敵國(guó)和親曲梗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容