<p>react-dnd๋Š” ๋งˆ์šดํŠธ๋˜์ง€ ์•Š์€ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ `Uncaught ์˜ค๋ฅ˜: ์œ ํšจํ•œ targetId๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค`๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.</p>

์— ๋งŒ๋“  2019๋…„ 06์›” 02์ผ  ยท  3์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: react-dnd/react-dnd

๋ฒ„๊ทธ ์„ค๋ช…
react-dnd๊ฐ€ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๋„๋ก ํ•˜๋Š” ์ˆ˜์ง‘ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ๋‹ค์Œ ๋งˆ์šดํŠธ ํ•ด์ œ๋œ ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•ด ๋˜ ๋‹ค๋ฅธ collect() ํ˜ธ์ถœ์„ ์ˆ˜ํ–‰ํ•˜์—ฌ "์˜ฌ๋ฐ”๋ฅธ targetId๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Œ" ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐฑ์—”๋“œ ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ ์ด๋ฒคํŠธ์˜ dispatch()์— ๋Œ€ํ•œ Redux๋Š” ์ฒ˜์Œ์— ๊ตฌ๋… ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ๋ชจ๋“  ์ˆ˜์‹ ๊ธฐ์˜ ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ค๊ณ  ๊ตฌ๋…์ž์—๊ฒŒ ์•Œ๋ฆฌ๋Š” ๋™์•ˆ ๊ตฌ๋… ์ทจ์†Œ๋œ redux ๊ตฌ๋…์— ๊ด€๊ณ„์—†์ด ํ•ญ์ƒ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค(https://stackoverflow.com/questions ์ฐธ์กฐ). /43356080/redux-unsubscribe-within-componentwillunmount-still-calls-subscribe-callback). ์ฆ‰, 'EndDrag' html5 ๋“œ๋ž˜๊ทธ ์ด๋ฒคํŠธ์™€ ๊ฐ™์€ ๊ฒƒ์ด react-dnd/src/decorateHandler.tsx:handleChange()์˜ handleChange()์—์„œ ์•Œ๋ฆผ์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๊ณ  ์ฒซ ๋ฒˆ์งธ collect() ํ˜ธ์ถœ๋กœ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋งˆ์šดํŠธ ํ•ด์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋งˆ์šดํŠธ ํ•ด์ œ๋œ ํ›„์† ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋™์ผํ•œ ์ด๋ฒคํŠธ์˜ ํ›„์† ์•Œ๋ฆผ์—์„œ ํ•ด๋‹น collect() ํ˜ธ์ถœ์ด ํŠธ๋ฆฌ๊ฑฐ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์œ ํšจํ•œ ๋Œ€์ƒ ID์˜ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ์œ ํšจํ•˜๊ฒŒ ์ œ๊ฑฐ๋˜์—ˆ์ง€๋งŒ ์•Œ๋ฆผ์ด ๋งˆ์šดํŠธ ํ•ด์ œ๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆ๋ณ€ '์œ ํšจํ•œ ๋Œ€์ƒ์„ ์ฐพ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋จ'์ด ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

react-dnd๋ฅผ ์‚ฌ์šฉํ•˜๋Š” react-sortable-tree๋ฅผ ๋‚ด ์•ฑ์— ํ†ตํ•ฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๋Š” ๋™์•ˆ ์ด ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. https://github.com/frontend-collective/react-sortable-tree/issues/490์—์„œ ๋ฌธ์ œ์˜ ์˜ˆ์™€ ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. dragTarget ์™ธ๋ถ€์—์„œ dragSource๋ฅผ ํ•ด์ œํ•˜์—ฌ ์ทจ์†Œ๋˜๋Š” ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ์€ ๋งค๋ฒˆ ์ด ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

ํฌ์ฐฉ๋˜์ง€ ์•Š์€ ์˜ค๋ฅ˜ ๋ฐ ์Šคํƒ ์ถ”์ ์ด ์•„๋ž˜์— ๋ถ™์—ฌ๋„ฃ์–ด์ง‘๋‹ˆ๋‹ค. ์Šคํƒ ์ถ”์ ์€ ์—ฐ๊ฒฐ ํ•จ์ˆ˜๊ฐ€ ๋งˆ์šดํŠธ ํ•ด์ œ๋œ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ์‹คํŒจํ•˜๋Š” monitor.canDrop()์„ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ์Œ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
browser.js:38 ์žกํžˆ์ง€ ์•Š์€ ๋ถˆ๋ณ€ ์œ„๋ฐ˜: ์œ ํšจํ•œ ๋Œ€์ƒ์„ ์ฐพ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค.๋ถˆ๋ณ€์—์„œ (https://xzoq6xprlz.codesandbox.io/node_modules/invariant/browser.js:38:15)DragDropMonitorImpl.canDropOnTarget์—์„œ (https://xzoq6xprlz.codesandbox.io/node_modules/dnd-core/lib/cjs/DragDropMonitorImpl.js:67:9)
DropTargetMonitorImpl.canDrop์—์„œ (https://xzoq6xprlz.codesandbox.io/node_modules/react-dnd/lib/cjs/DropTargetMonitorImpl.js:24:41)
nodeDropTargetPropInjection์—์„œ (https://xzoq6xprlz.codesandbox.io/node_modules/react-sortable-tree/dist/index.cjs.js:2367:28)
DragDropContainer.getCurrentState์—์„œ (https://xzoq6xprlz.codesandbox.io/node_modules/react-dnd/lib/cjs/decorateHandler.js:116:29)
DragDropContainer._this.handleChange์—์„œ (https://xzoq6xprlz.codesandbox.io/node_modules/react-dnd/lib/cjs/decorateHandler.js:45:39)
ํ•ธ๋“ค ๋ณ€๊ฒฝ ์‹œ(https://xzoq6xprlz.codesandbox.io/node_modules/dnd-core/lib/cjs/DragDropMonitorImpl.js:27:21)
ํŒŒ๊ฒฌ ์‹œ (https://xzoq6xprlz.codesandbox.io/node_modules/redux/lib/redux.js:220:7)
Object.eval์—์„œ [endDrag๋กœ] (https://xzoq6xprlz.codesandbox.io/node_modules/dnd-core/lib/cjs/DragDropManagerImpl.js:67:21)
HTML5Backend.handleTopDragEndCapture์—์„œ (https://xzoq6xprlz.codesandbox.io/node_modules/react-dnd-html5-backend/lib/cjs/HTML5Backend.js:145:31)
``

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๋งˆ์šดํŠธ ํ•ด์ œ๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ์•„๋งˆ๋„ ์˜ฌ๋ฐ”๋ฅธ ๋™์ž‘์ด ์•„๋‹ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, decorHandler๊ฐ€ ์ด๋ฏธ ๊ตฌ๋… ์ทจ์†Œ๋œ ๊ฒฝ์šฐ ์•Œ๋ฆผ์„ ์‚ญ์ œํ•˜๋Š” if ๋ฌธ์„ react-dnd/src/decorateHandler.tsx:handleChange์— ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. diff ์ฒจ๋ถ€.

diff --git a/packages/react-dnd/src/decorateHandler.tsx b/packages/react-dnd/src/decorateHandler.tsx
index 85385ec..bcd149e 100644
--- a/packages/react-dnd/src/decorateHandler.tsx
+++ b/packages/react-dnd/src/decorateHandler.tsx
@@ -159,6 +159,15 @@ export default function decorateHandler<Props, CollectedProps, ItemIdType>({
                }

                public handleChange = () => {
+                       if (this.disposable.isDisposed) {
+                               console.log("in handleChange")
+                               //because redux takes a snapshot of all subscribers to 
+                               //events when it starts dispatch, it is still possible to call into this even after 
+                               //the subscription has been unsubscribed
+                               //to prevent against calling into unmounted objects, return immediately
+
+                               return
+                       }
                        const nextState = this.getCurrentState()
                        if (!shallowEqual(nextState, this.state)) {
                                this.setState(nextState)

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@mx2323 ์ด๊ฑฐ ๋ฐ€๋ฆฐ๊ฑด๊ฐ€์š”? ๊ทธ๊ฒƒ์ด react-sortable-tree ์˜€๋”๋ผ๋„ ์—ฌ์ „ํžˆ ์ตœ์‹  react-dnd ์—…๋ฐ์ดํŠธ๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ค‘์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  3 ๋Œ“๊ธ€

์ด ๋ฌธ์ œ๋Š” ์ตœ๊ทผ ํ™œ๋™์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž๋™์œผ๋กœ ์˜ค๋ž˜๋œ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋” ์ด์ƒ ํ™œ๋™์ด ์—†์œผ๋ฉด ํ์‡„๋ฉ๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ๊ธฐ์—ฌ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

@mx2323 ์ด๊ฑฐ ๋ฐ€๋ฆฐ๊ฑด๊ฐ€์š”? ๊ทธ๊ฒƒ์ด react-sortable-tree ์˜€๋”๋ผ๋„ ์—ฌ์ „ํžˆ ์ตœ์‹  react-dnd ์—…๋ฐ์ดํŠธ๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ค‘์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๋ฐ€๊ณ  ๋๋‚ด์ง€ ์•Š์•˜๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰