@@ -130,6 +130,8 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
130130
131131 itemsRef : React . MutableRefObject < UploadItem [ ] > ;
132132
133+ itemIdsRef : React . MutableRefObject < Object > ;
134+
133135 static defaultProps = {
134136 apiHost : DEFAULT_HOSTNAME_API ,
135137 chunked : true ,
@@ -182,6 +184,9 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
182184
183185 this . itemsRef = React . createRef ( ) ;
184186 this . itemsRef . current = [ ] ;
187+
188+ this . itemIdsRef = React . createRef ( ) ;
189+ this . itemIdsRef . current = { } ;
185190 }
186191
187192 /**
@@ -289,9 +294,8 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
289294 */
290295 getNewFiles = ( files : Array < UploadFileWithAPIOptions | File > ) : Array < UploadFileWithAPIOptions | File > => {
291296 const { rootFolderId } = this . props ;
292- const { itemIds } = this . state ;
293297
294- return Array . from ( files ) . filter ( file => ! itemIds [ getFileId ( file , rootFolderId ) ] ) ;
298+ return Array . from ( files ) . filter ( file => ! this . itemIdsRef . current [ getFileId ( file , rootFolderId ) ] ) ;
295299 } ;
296300
297301 /**
@@ -303,9 +307,8 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
303307 items : Array < DataTransferItem | UploadDataTransferItemWithAPIOptions > ,
304308 ) : Array < DataTransferItem | UploadDataTransferItemWithAPIOptions > => {
305309 const { rootFolderId } = this . props ;
306- const { itemIds } = this . state ;
307310
308- return Array . from ( items ) . filter ( item => ! itemIds [ getDataTransferItemId ( item , rootFolderId ) ] ) ;
311+ return Array . from ( items ) . filter ( item => ! this . itemIdsRef . current [ getDataTransferItemId ( item , rootFolderId ) ] ) ;
309312 } ;
310313
311314 /**
@@ -342,26 +345,22 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
342345
343346 const firstFile = getFile ( newFiles [ 0 ] ) ;
344347
345- this . setState (
346- state => ( {
347- itemIds : {
348- ...state . itemIds ,
349- ...newItemIds ,
350- } ,
351- } ) ,
352- ( ) => {
353- onBeforeUpload ( newFiles ) ;
354- if ( firstFile . webkitRelativePath && ! isRelativePathIgnored ) {
355- // webkitRelativePath should be ignored when the upload destination folder is known
356- this . addFilesWithRelativePathToQueue ( newFiles , itemUpdateCallback ) ;
357- } else {
358- this . addFilesWithoutRelativePathToQueue (
359- newFiles ,
360- isPrepopulateFilesEnabled ? this . upload : itemUpdateCallback ,
361- ) ;
362- }
363- } ,
364- ) ;
348+ const newItemIdsState = { ...this . itemsRef . current , ...newItemIds } ;
349+
350+ this . itemIdsRef . current = newItemIdsState ;
351+
352+ this . setState ( { itemIds : newItemIdsState } , ( ) => {
353+ onBeforeUpload ( newFiles ) ;
354+ if ( firstFile . webkitRelativePath && ! isRelativePathIgnored ) {
355+ // webkitRelativePath should be ignored when the upload destination folder is known
356+ this . addFilesWithRelativePathToQueue ( newFiles , itemUpdateCallback ) ;
357+ } else {
358+ this . addFilesWithoutRelativePathToQueue (
359+ newFiles ,
360+ isPrepopulateFilesEnabled ? this . upload : itemUpdateCallback ,
361+ ) ;
362+ }
363+ } ) ;
365364 } ;
366365
367366 /**
@@ -469,15 +468,14 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
469468 itemUpdateCallback : Function ,
470469 ) : void => {
471470 const { rootFolderId } = this . props ;
472- const { itemIds } = this . state ;
473471
474472 if ( dataTransferItems . length === 0 ) {
475473 return ;
476474 }
477475
478476 const newItems = this . getNewDataTransferItems ( dataTransferItems ) ;
479477 newItems . forEach ( item => {
480- itemIds [ getDataTransferItemId ( item , rootFolderId ) ] = true ;
478+ this . itemIdsRef . current [ getDataTransferItemId ( item , rootFolderId ) ] = true ;
481479 } ) ;
482480
483481 if ( newItems . length === 0 ) {
@@ -581,7 +579,6 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
581579 files : Array < UploadFileWithAPIOptions | File > ,
582580 itemUpdateCallback : Function ,
583581 ) => {
584- const { itemIds } = this . state ;
585582 const { rootFolderId } = this . props ;
586583
587584 // Convert files from the file API to upload items
@@ -611,7 +608,7 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
611608 uploadItem . options = uploadAPIOptions ;
612609 }
613610
614- itemIds [ getFileId ( uploadItem , rootFolderId ) ] = true ;
611+ this . itemIdsRef . current [ getFileId ( uploadItem , rootFolderId ) ] = true ;
615612
616613 return uploadItem ;
617614 } ) ;
@@ -621,7 +618,7 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
621618 }
622619
623620 this . setState ( {
624- itemIds,
621+ itemIds : this . itemIdsRef . current ,
625622 } ) ;
626623 this . addToQueue ( newItems , itemUpdateCallback ) ;
627624 } ;
@@ -664,8 +661,6 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
664661 }
665662 }
666663
667- this . itemsRef . current = updatedItems ;
668-
669664 this . updateViewAndCollection ( updatedItems , ( ) => {
670665 if ( itemUpdateCallback ) {
671666 itemUpdateCallback ( ) ;
@@ -727,19 +722,21 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
727722 */
728723 removeFileFromUploadQueue = ( item : UploadItem ) => {
729724 const { onCancel, useUploadsManager } = this . props ;
730- const { items } = this . state ;
731725 // Clear any error errorCode in footer
732726 this . setState ( { errorCode : '' } ) ;
733727
734728 const { api } = item ;
735729 api . cancel ( ) ;
736730
737- items . splice ( items . indexOf ( item ) , 1 ) ;
731+ const itemIndex = this . itemsRef . current . indexOf ( item ) ;
732+ const updatedItems = this . itemsRef . current
733+ . slice ( 0 , itemIndex )
734+ . concat ( this . itemsRef . current . slice ( itemIndex + 1 ) ) ;
738735
739736 onCancel ( [ item ] ) ;
740- this . updateViewAndCollection ( items , ( ) => {
737+ this . updateViewAndCollection ( updatedItems , ( ) => {
741738 // Minimize uploads manager if there are no more items
742- if ( useUploadsManager && ! items . length ) {
739+ if ( useUploadsManager && ! updatedItems . length ) {
743740 this . minimizeUploadsManager ( ) ;
744741 }
745742
@@ -757,8 +754,7 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
757754 * @return {void }
758755 */
759756 cancel = ( ) => {
760- const { items } = this . state ;
761- items . forEach ( uploadItem => {
757+ this . itemsRef . current . forEach ( uploadItem => {
762758 const { api, status } = uploadItem ;
763759 if ( status === STATUS_IN_PROGRESS ) {
764760 api . cancel ( ) ;
@@ -776,8 +772,7 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
776772 * @return {void }
777773 */
778774 upload = ( ) => {
779- const { items } = this . state ;
780- items . forEach ( uploadItem => {
775+ this . itemsRef . current . forEach ( uploadItem => {
781776 if ( uploadItem . status === STATUS_PENDING ) {
782777 this . uploadFile ( uploadItem ) ;
783778 }
@@ -792,10 +787,9 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
792787 */
793788 uploadFile ( item : UploadItem ) {
794789 const { overwrite, rootFolderId } = this . props ;
795- const { items } = this . state ;
796790 const { api, file, options } = item ;
797791
798- const numItemsUploading = items . filter ( item_t => item_t . status === STATUS_IN_PROGRESS ) . length ;
792+ const numItemsUploading = this . itemsRef . current . filter ( item_t => item_t . status === STATUS_IN_PROGRESS ) . length ;
799793
800794 if ( numItemsUploading >= UPLOAD_CONCURRENCY ) {
801795 return ;
@@ -812,11 +806,12 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
812806 } ;
813807
814808 item . status = STATUS_IN_PROGRESS ;
815- items [ items . indexOf ( item ) ] = item ;
809+ const updatedItems = [ ...this . itemsRef . current ] ;
810+ updatedItems [ this . itemsRef . current . indexOf ( item ) ] = item ;
816811
817812 api . upload ( uploadOptions ) ;
818813
819- this . updateViewAndCollection ( items ) ;
814+ this . updateViewAndCollection ( updatedItems ) ;
820815 }
821816
822817 /**
@@ -827,10 +822,9 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
827822 */
828823 resumeFile ( item : UploadItem ) {
829824 const { onResume, overwrite, rootFolderId } = this . props ;
830- const { items } = this . state ;
831825 const { api, file, options } = item ;
832826
833- const numItemsUploading = items . filter ( item_t => item_t . status === STATUS_IN_PROGRESS ) . length ;
827+ const numItemsUploading = this . itemsRef . current . filter ( item_t => item_t . status === STATUS_IN_PROGRESS ) . length ;
834828
835829 if ( numItemsUploading >= UPLOAD_CONCURRENCY ) {
836830 return ;
@@ -849,12 +843,14 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
849843
850844 item . status = STATUS_IN_PROGRESS ;
851845 delete item . error ;
852- items [ items . indexOf ( item ) ] = item ;
846+
847+ const updatedItems = [ ...this . itemsRef . current ] ;
848+ updatedItems [ this . itemsRef . current . indexOf ( item ) ] = item ;
853849
854850 onResume ( item ) ;
855851 api . resume ( resumeOptions ) ;
856852
857- this . updateViewAndCollection ( items ) ;
853+ this . updateViewAndCollection ( updatedItems ) ;
858854 }
859855
860856 /**
@@ -875,10 +871,10 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
875871 item . status = STATUS_PENDING ;
876872 delete item . error ;
877873
878- const { items } = this . state ;
879- items [ items . indexOf ( item ) ] = item ;
874+ const updatedItems = [ ... this . itemsRef . current ] ;
875+ updatedItems [ this . itemsRef . current . indexOf ( item ) ] = item ;
880876
881- this . updateViewAndCollection ( items ) ;
877+ this . updateViewAndCollection ( updatedItems ) ;
882878 }
883879
884880 /**
@@ -903,8 +899,8 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
903899 item . boxFile = boxFile ;
904900 }
905901
906- const { items } = this . state ;
907- items [ items . indexOf ( item ) ] = item ;
902+ const updatedItems = [ ... this . itemsRef . current ] ;
903+ updatedItems [ this . itemsRef . current . indexOf ( item ) ] = item ;
908904
909905 // Broadcast that a file has been uploaded
910906 if ( useUploadsManager ) {
@@ -914,7 +910,7 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
914910 onUpload ( item . boxFile ) ;
915911 }
916912
917- this . updateViewAndCollection ( items , ( ) => {
913+ this . updateViewAndCollection ( updatedItems , ( ) => {
918914 const { view } = this . state ;
919915 if ( view === VIEW_UPLOAD_IN_PROGRESS ) {
920916 this . upload ( ) ;
@@ -994,10 +990,13 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
994990 } ;
995991
996992 if ( items . length === 0 ) {
993+ this . itemIdsRef . current = { } ;
997994 state . itemIds = { } ;
998995 state . errorCode = '' ;
999996 }
1000997
998+ this . itemsRef . current = items ;
999+
10011000 this . setState ( state as Pick < State , keyof State > , callback ) ;
10021001 }
10031002
@@ -1011,13 +1010,12 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
10111010 */
10121011 handleUploadError = ( item : UploadItem , error : Error ) => {
10131012 const { onError, useUploadsManager } = this . props ;
1014- const { items } = this . state ;
10151013 const { file } = item ;
10161014
10171015 item . status = STATUS_ERROR ;
10181016 item . error = error ;
10191017
1020- const newItems = [ ...items ] ;
1018+ const newItems = [ ...this . itemsRef . current ] ;
10211019 const index = newItems . findIndex ( singleItem => singleItem === item ) ;
10221020 if ( index !== - 1 ) {
10231021 newItems [ index ] = item ;
@@ -1067,10 +1065,10 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
10671065 const { onProgress } = this . props ;
10681066 onProgress ( item ) ;
10691067
1070- const { items } = this . state ;
1071- items [ items . indexOf ( item ) ] = item ;
1068+ const updatedItems = [ ... this . itemsRef . current ] ;
1069+ updatedItems [ this . itemsRef . current . indexOf ( item ) ] = item ;
10721070
1073- this . updateViewAndCollection ( items ) ;
1071+ this . updateViewAndCollection ( updatedItems ) ;
10741072 } ;
10751073
10761074 /**
@@ -1119,9 +1117,7 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
11191117 * @return {void }
11201118 */
11211119 clickAllWithStatus = ( status ?: UploadStatus ) => {
1122- const { items } = this . state ;
1123-
1124- items . forEach ( item => {
1120+ this . itemsRef . current . forEach ( item => {
11251121 if ( ! status || item . status === status ) {
11261122 this . onClick ( item ) ;
11271123 }
@@ -1198,14 +1194,20 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
11981194 */
11991195 resetUploadsManagerItemsWhenUploadsComplete = ( ) : void => {
12001196 const { onCancel, useUploadsManager } = this . props ;
1201- const { isUploadsManagerExpanded, items , view } = this . state ;
1197+ const { isUploadsManagerExpanded, view } = this . state ;
12021198
12031199 // Do not reset items when upload manger is expanded or there're uploads in progress
1204- if ( ( isUploadsManagerExpanded && useUploadsManager && ! ! items . length ) || view === VIEW_UPLOAD_IN_PROGRESS ) {
1200+ if (
1201+ ( isUploadsManagerExpanded && useUploadsManager && ! ! this . itemsRef . current . length ) ||
1202+ view === VIEW_UPLOAD_IN_PROGRESS
1203+ ) {
12051204 return ;
12061205 }
12071206
1208- onCancel ( items ) ;
1207+ onCancel ( this . itemsRef . current ) ;
1208+
1209+ this . itemsRef . current = [ ] ;
1210+ this . itemIdsRef . current = { } ;
12091211
12101212 this . setState ( {
12111213 items : [ ] ,
0 commit comments