From a7eef4dab596145594c282d48e3033516115587d Mon Sep 17 00:00:00 2001 From: Lin Wang Date: Mon, 27 Nov 2023 15:54:23 +0800 Subject: [PATCH] refactor: replace genericReducerWithAbortController with useRef Signed-off-by: Lin Wang --- .../edit_conversation_name_modal.tsx | 6 +-- public/hooks/fetch_reducer.ts | 37 ------------------- public/hooks/use_sessions.ts | 32 +++++++++++----- .../delete_conversation_confirm_modal.tsx | 8 ++-- 4 files changed, 29 insertions(+), 54 deletions(-) diff --git a/public/components/edit_conversation_name_modal.tsx b/public/components/edit_conversation_name_modal.tsx index dffa2c08..e513c2f0 100644 --- a/public/components/edit_conversation_name_modal.tsx +++ b/public/components/edit_conversation_name_modal.tsx @@ -20,12 +20,12 @@ export const EditConversationNameModal = ({ defaultTitle, }: EditConversationNameModalProps) => { const titleInputRef = useRef(null); - const { loading, abortController, patchSession } = usePatchSession(); + const { loading, abort, patchSession } = usePatchSession(); const handleCancel = useCallback(() => { - abortController?.abort(); + abort(); onClose?.('cancelled'); - }, [onClose, abortController]); + }, [onClose, abort]); const handleConfirm = useCallback(async () => { const title = titleInputRef.current?.value.trim(); if (!title) { diff --git a/public/hooks/fetch_reducer.ts b/public/hooks/fetch_reducer.ts index 6cbd88b6..35b2f888 100644 --- a/public/hooks/fetch_reducer.ts +++ b/public/hooks/fetch_reducer.ts @@ -34,40 +34,3 @@ export const genericReducer: GenericReducer = (state, action) => { return state; } }; - -interface StateWithAbortController { - data?: T; - loading: boolean; - error?: Error; - abortController?: AbortController; -} - -type ActionWithAbortController = - | { type: 'request'; abortController: AbortController } - | { type: 'success'; payload: State['data'] } - | { - type: 'failure'; - error: NonNullable['error']> | { body: NonNullable['error']> }; - }; - -// TODO use instantiation expressions when typescript is upgraded to >= 4.7 -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export type GenericReducerWithAbortController = Reducer< - StateWithAbortController, - ActionWithAbortController ->; -export const genericReducerWithAbortController: GenericReducerWithAbortController = ( - state, - action -) => { - switch (action.type) { - case 'request': - return { data: state.data, loading: true, abortController: action.abortController }; - case 'success': - return { loading: false, data: action.payload }; - case 'failure': - return { loading: false, error: 'body' in action.error ? action.error.body : action.error }; - default: - return state; - } -}; diff --git a/public/hooks/use_sessions.ts b/public/hooks/use_sessions.ts index 1f0789bd..1300f356 100644 --- a/public/hooks/use_sessions.ts +++ b/public/hooks/use_sessions.ts @@ -3,22 +3,23 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { useCallback, useReducer } from 'react'; +import { useCallback, useReducer, useRef } from 'react'; import { ASSISTANT_API } from '../../common/constants/llm'; import { useCore } from '../contexts/core_context'; -import { genericReducerWithAbortController } from './fetch_reducer'; +import { genericReducer } from './fetch_reducer'; export const useDeleteSession = () => { const core = useCore(); - const [state, dispatch] = useReducer(genericReducerWithAbortController, { loading: false }); + const [state, dispatch] = useReducer(genericReducer, { loading: false }); + const abortControllerRef = useRef(); const deleteSession = useCallback( (sessionId: string) => { - const abortController = new AbortController(); - dispatch({ type: 'request', abortController }); + abortControllerRef.current = new AbortController(); + dispatch({ type: 'request' }); return core.services.http .delete(`${ASSISTANT_API.SESSION}/${sessionId}`, { - signal: abortController.signal, + signal: abortControllerRef.current.signal, }) .then((payload) => dispatch({ type: 'success', payload })) .catch((error) => dispatch({ type: 'failure', error })); @@ -26,26 +27,32 @@ export const useDeleteSession = () => { [core.services.http] ); + const abort = useCallback(() => { + abortControllerRef.current?.abort(); + }, []); + return { ...state, + abort, deleteSession, }; }; export const usePatchSession = () => { const core = useCore(); - const [state, dispatch] = useReducer(genericReducerWithAbortController, { loading: false }); + const [state, dispatch] = useReducer(genericReducer, { loading: false }); + const abortControllerRef = useRef(); const patchSession = useCallback( (sessionId: string, title: string) => { - const abortController = new AbortController(); - dispatch({ type: 'request', abortController }); + abortControllerRef.current = new AbortController(); + dispatch({ type: 'request' }); return core.services.http .put(`${ASSISTANT_API.SESSION}/${sessionId}`, { query: { title, }, - signal: abortController.signal, + signal: abortControllerRef.current.signal, }) .then((payload) => dispatch({ type: 'success', payload })) .catch((error) => dispatch({ type: 'failure', error })); @@ -53,8 +60,13 @@ export const usePatchSession = () => { [core.services.http] ); + const abort = useCallback(() => { + abortControllerRef.current?.abort(); + }, []); + return { ...state, + abort, patchSession, }; }; diff --git a/public/tabs/history/delete_conversation_confirm_modal.tsx b/public/tabs/history/delete_conversation_confirm_modal.tsx index adddd957..b0e66374 100644 --- a/public/tabs/history/delete_conversation_confirm_modal.tsx +++ b/public/tabs/history/delete_conversation_confirm_modal.tsx @@ -18,12 +18,12 @@ export const DeleteConversationConfirmModal = ({ onClose, sessionId, }: DeleteConversationConfirmModalProps) => { - const { loading, data, deleteSession, abortController } = useDeleteSession(); + const { loading, deleteSession, abort } = useDeleteSession(); const handleCancel = useCallback(() => { - abortController?.abort(); + abort(); onClose?.('canceled'); - }, [onClose, abortController]); + }, [onClose, abort]); const handleConfirm = useCallback(async () => { try { await deleteSession(sessionId); @@ -32,7 +32,7 @@ export const DeleteConversationConfirmModal = ({ return; } onClose?.('deleted'); - }, [onClose, deleteSession]); + }, [onClose, deleteSession, sessionId]); return (