11import type { DElementSelector } from '../../hooks/element-ref' ;
22import type { DDragProps } from './Drag' ;
33
4- import { isEqual , isUndefined } from 'lodash' ;
5- import React , { useImperativeHandle , useRef } from 'react' ;
4+ import { cloneDeep , isEqual , isUndefined } from 'lodash' ;
5+ import React , { useImperativeHandle , useRef , useState } from 'react' ;
66import { useEffect , useMemo } from 'react' ;
77
88import { useDComponentConfig , useRefSelector , useImmer } from '../../hooks' ;
@@ -46,20 +46,14 @@ export const DDrop = React.forwardRef<DDropRef, DDropProps>((props, ref) => {
4646 onDragEnd,
4747 } = useDComponentConfig ( 'drop' , props ) ;
4848
49- const dataRef = useRef <
50- DDropContextData [ 'dropCurrentData' ] & {
51- order : string [ ] ;
52- preOrder ?: string [ ] ;
53- }
54- > ( {
49+ const dataRef = useRef < DDropContextData [ 'dropCurrentData' ] > ( {
5550 drags : new Map ( ) ,
5651 placeholders : new Map ( ) ,
57- order : Array < string > ( ) ,
5852 } ) ;
5953
60- const [ updateChildren , setUpdateChildren ] = useImmer ( 0 ) ;
6154 const [ isOuter , setIsOuter ] = useImmer ( false ) ;
6255
56+ const [ orderIds , setOrderIds ] = useState < string [ ] > ( [ ] ) ;
6357 const [ orderChildren , setOrderChildren ] = useImmer < React . ReactElement [ ] > ( [ ] ) ;
6458
6559 const containerRef = useRefSelector ( dContainer ) ;
@@ -68,24 +62,27 @@ export const DDrop = React.forwardRef<DDropRef, DDropProps>((props, ref) => {
6862 useEffect ( ( ) => {
6963 const _childs = React . Children . toArray ( children ) as Array < React . ReactElement < DDragProps > > ;
7064 const allIds = _childs . map ( ( child ) => child . props . dId as string ) ;
71- dataRef . current . order = dataRef . current . order . filter ( ( id ) => allIds . includes ( id ) ) ;
72- dataRef . current . order . length = allIds . length ;
73- const addIndex = allIds . findIndex ( ( id ) => ! dataRef . current . order . includes ( id ) ) ;
65+ const newOrderIds = cloneDeep ( orderIds . filter ( ( id ) => allIds . includes ( id ) ) ) ;
66+ newOrderIds . length = allIds . length ;
67+ const addIndex = allIds . findIndex ( ( id ) => ! newOrderIds . includes ( id ) ) ;
7468 if ( addIndex !== - 1 ) {
7569 const addIds : string [ ] = [ ] ;
7670 for ( let n = addIndex ; n < allIds . length ; n ++ ) {
77- if ( ! dataRef . current . order . includes ( allIds [ n ] ) ) {
71+ if ( ! newOrderIds . includes ( allIds [ n ] ) ) {
7872 addIds . push ( allIds [ n ] ) ;
7973 } else {
8074 break ;
8175 }
8276 }
83- dataRef . current . order . splice ( addIndex , 0 , ...addIds ) ;
77+ newOrderIds . splice ( addIndex , 0 , ...addIds ) ;
8478 }
8579
80+ if ( ! isEqual ( newOrderIds , orderIds ) ) {
81+ setOrderIds ( newOrderIds ) ;
82+ }
8683 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
87- setOrderChildren ( dataRef . current . order . map ( ( id ) => _childs . find ( ( child ) => child . props . dId === id ) ! ) ) ;
88- } , [ children , updateChildren , setOrderChildren ] ) ;
84+ setOrderChildren ( newOrderIds . map ( ( id ) => _childs . find ( ( child ) => child . props . dId === id ) ! ) ) ;
85+ } , [ children , setOrderChildren , orderIds , setOrderIds ] ) ;
8986 //#endregion
9087
9188 const contextValue = useMemo < DDropContextData > (
@@ -145,7 +142,9 @@ export const DDrop = React.forwardRef<DDropRef, DDropProps>((props, ref) => {
145142 top : rect . top + rect . height / 2 ,
146143 left : rect . left + rect . width / 2 ,
147144 } ;
148- dataRef . current . order . forEach ( ( id , index ) => {
145+
146+ let newOrderIds = cloneDeep ( orderIds ) ;
147+ newOrderIds . forEach ( ( id , index ) => {
149148 let el : HTMLElement | null = null ;
150149 if ( id === dragId ) {
151150 const selector = dataRef . current . placeholders . get ( id ) ;
@@ -175,34 +174,32 @@ export const DDrop = React.forwardRef<DDropRef, DDropProps>((props, ref) => {
175174 }
176175 }
177176 } ) ;
178-
179177 if ( ! isUndefined ( replaceIndex ) ) {
180- dataRef . current . order . splice (
181- dataRef . current . order . findIndex ( ( id ) => id === dragId ) ,
178+ newOrderIds . splice (
179+ newOrderIds . findIndex ( ( id ) => id === dragId ) ,
182180 1 ,
183181 // eslint-disable-next-line @typescript-eslint/no-explicit-any
184182 undefined as any
185183 ) ;
186184
187- dataRef . current . order . splice ( replaceIndex , 0 , dragId as string ) ;
185+ newOrderIds . splice ( replaceIndex , 0 , dragId as string ) ;
188186
189- dataRef . current . order = dataRef . current . order . filter ( ( id ) => ! ! id ) ;
187+ newOrderIds = newOrderIds . filter ( ( id ) => ! ! id ) ;
188+ }
190189
191- if ( ! isEqual ( dataRef . current . preOrder , dataRef . current . order ) ) {
192- dataRef . current . preOrder = [ ...dataRef . current . order ] ;
193- setUpdateChildren ( ( prev ) => prev + 1 ) ;
194- onOrderChange ?.( dataRef . current . order ) ;
195- }
190+ if ( ! isEqual ( newOrderIds , orderIds ) ) {
191+ setOrderIds ( newOrderIds ) ;
192+ onOrderChange ?.( newOrderIds ) ;
196193 }
197194 } ,
198195 onDragEnd : ( id ) => {
199196 onDragEnd ?.( id ) ;
200197 } ,
201198 } ) ,
202- [ dDirection , isOuter , dPlaceholder , onDragStart , onDrag , containerRef , setIsOuter , setUpdateChildren , onOrderChange , onDragEnd ]
199+ [ containerRef , dDirection , dPlaceholder , isOuter , onDrag , onDragEnd , onDragStart , onOrderChange , orderIds , setIsOuter , setOrderIds ]
203200 ) ;
204201
205- useImperativeHandle ( ref , ( ) => dataRef . current . order , [ ] ) ;
202+ useImperativeHandle ( ref , ( ) => orderIds , [ orderIds ] ) ;
206203
207204 return < DDropContext . Provider value = { contextValue } > { orderChildren } </ DDropContext . Provider > ;
208205} ) ;
0 commit comments