fix: frontend could request list twice (especially in dev)

Massimo Melina committed Jan 8, 2023 at 11:29 UTC bdeb89859b4a5098b9fefc1a375643ba9505d492
2 files changed +12 -14
frontend/src/useFetchList.ts
+10 -2
@@ -6,13 +6,17 @@ import { apiEvents } from './api'
6 import { DirEntry, DirList, usePath } from './BrowseFiles'
7 import _ from 'lodash'
8 import { subscribeKey } from 'valtio/utils'
9 +import { useIsMounted } from 'usehooks-ts'
10 +
11 +const API = 'file_list'
12
13 export default function useFetchList() {
14 const snap = useSnapState()
15 const desiredPath = usePath()
16 const search = snap.remoteSearch || undefined
17 const lastPath = useRef('')
15 -
18 + const lastReq = useRef<any>()
19 + const isMounted = useIsMounted()
20 useEffect(()=>{
21 const previous = lastPath.current
22 lastPath.current = desiredPath
@@ -26,8 +30,10 @@ export default function useFetchList() {
30 return
31 }
32
29 - const API = 'file_list'
33 const baseParams = { path:desiredPath, search, sse:true, omit:'c' }
34 + if (_.isEqual(baseParams, lastReq.current)) return
35 + lastReq.current = baseParams
36 +
37 state.list = []
38 state.filteredList = undefined
39 state.selected = {}
@@ -42,6 +48,7 @@ export default function useFetchList() {
48 }
49 const timer = setInterval(flush, 1000)
50 const src = apiEvents(API, baseParams, (type, data) => {
51 + if (!isMounted()) return
52 switch (type) {
53 case 'error':
54 state.stopSearch?.()
@@ -51,6 +58,7 @@ export default function useFetchList() {
58 flush()
59 state.stopSearch?.()
60 state.loading = false
61 + lastReq.current = undefined
62 return
63 case 'msg':
64 data.forEach((data: any) => {
shared/react.ts
+2 -12
@@ -1,17 +1,7 @@
1 // This file is part of HFS - Copyright 2021-2022, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3 -import { createElement as h, Fragment, ReactElement, ReactNode, useCallback, useEffect, useRef, useState } from 'react'
4 -
5 -export function useIsMounted() {
6 - const mountRef = useRef(false)
7 - useEffect(() => {
8 - mountRef.current = true
9 - return () => {
10 - mountRef.current = false
11 - }
12 - }, [])
13 - return useCallback(()=> mountRef.current, [mountRef])
14 -}
3 +import { createElement as h, Fragment, ReactElement, ReactNode, useCallback, useState } from 'react'
4 +import { useIsMounted } from 'usehooks-ts'
5
6 export function useStateMounted<T>(init: T) {
7 const isMounted = useIsMounted()