"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > 순차적 요청을 처리하는 React Hook을 구축하는 방법

순차적 요청을 처리하는 React Hook을 구축하는 방법

2024-11-04에 게시됨
검색:305

사용자 작업에 빠르게 응답하고 백엔드에서 최신 데이터를 가져와야 하는 경우 순차적 요청을 지원하는 React Hook이 필요할 수 있습니다. 이 후크는 이전 요청이 아직 진행 중인 경우 취소하고 가장 최근 데이터만 반환할 수 있습니다. 이는 성능을 향상시킬 뿐만 아니라 사용자 경험도 향상시킵니다.

간단한 순차적 요청 React Hook 구축

간단한 순차 요청 React 후크를 구축하는 것부터 시작해 보겠습니다.

import { useCallback, useRef } from 'react';
​
const buildCancelableFetch = (
  requestFn: (signal: AbortSignal) => Promise,
) => {
  const abortController = new AbortController();
​
  return {
    run: () =>
      new Promise((resolve, reject) => {
        if (abortController.signal.aborted) {
          reject(new Error('CanceledError'));
          return;
        }
​
        requestFn(abortController.signal).then(resolve, reject);
      }),
​
    cancel: () => {
      abortController.abort();
    },
  };
};
​
function useLatest(value: T) {
  const ref = useRef(value);
  ref.current = value;
  return ref;
}
​
export function useSequentialRequest(
  requestFn: (signal: AbortSignal) => Promise,
) {
  const requestFnRef = useLatest(requestFn);
  const currentRequest = useRef void } | null>(null);
​
  return useCallback(async () => {
    if (currentRequest.current) {
      currentRequest.current.cancel();
    }
​
    const { run, cancel } = buildCancelableFetch(requestFnRef.current);
    currentRequest.current = { cancel };
​
    return run().finally(() => {
      if (currentRequest.current?.cancel === cancel) {
        currentRequest.current = null;
      }
    });
  }, [requestFnRef]);
}

여기서 핵심 아이디어는 "JavaScript에서 약속을 취소하는 방법" 기사에서 나왔습니다. 다음과 같이 사용할 수 있습니다:

import { useSequentialRequest } from './useSequentialRequest';
​
export function App() {
  const run = useSequentialRequest((signal: AbortSignal) =>
    fetch('http://localhost:5000', { signal }).then((res) => res.text()),
  );
​
  return ;
}

이렇게 하면 버튼을 여러 번 빠르게 클릭하면 최근 요청의 데이터만 가져오고 이전 요청은 삭제됩니다.

How to Build a React Hook That Handles Sequential Requests

최적화된 순차적 요청 React Hook 구축

보다 포괄적인 순차 요청 React Hook이 필요한 경우 위 코드에 개선의 여지가 있습니다. 예를 들어:

  • 실제로 필요할 때까지 AbortController 생성을 연기하여 불필요한 생성 비용을 줄일 수 있습니다.

  • 일반 사항을 사용하여 모든 유형의 요청 인수를 지원할 수 있습니다.

업데이트된 버전은 다음과 같습니다.

import { useCallback, useRef } from 'react';
​
function useLatest(value: T) {
  const ref = useRef(value);
  ref.current = value;
  return ref;
}
​
export function useSequentialRequest(
  requestFn: (signal: AbortSignal, ...args: Args) => Promise,
) {
  const requestFnRef = useLatest(requestFn);
​
  const running = useRef(false);
  const abortController = useRef(null);
​
  return useCallback(
    async (...args: Args) => {
      if (running.current) {
        abortController.current?.abort();
        abortController.current = null;
      }
​
      running.current = true;
​
      const controller = abortController.current ?? new AbortController();
      abortController.current = controller;
​
      return requestFnRef.current(controller.signal, ...args).finally(() => {
        if (controller === abortController.current) {
          running.current = false;
        }
      });
    },
    [requestFnRef],
  );
}

finally 블록에서는 경쟁 조건을 방지하기 위해 현재 컨트롤러가 abortController.current와 같은지 확인합니다. 이렇게 하면 활성 요청만 실행 상태를 수정할 수 있습니다.

보다 포괄적인 사용법:

import { useState } from 'react';
import { useSequentialRequest } from './useSequentialRequest';
​
export default function Home() {
  const [data, setData] = useState('');
​
  const run = useSequentialRequest(async (signal: AbortSignal, query: string) =>
    fetch(`/api/hello?query=${query}`, { signal }).then((res) => res.text()),
  );
​
  const handleInput = async (queryStr: string) => {
    try {
      const res = await run(queryStr);
      setData(res);
    } catch {
      // ignore errors
    }
  };
​
  return (
    
       {
          handleInput(e.target.value);
        }}
      />
      
Response Data: {data}
> ); }

온라인으로 시도해 볼 수 있습니다. 빠르게 입력하면 이전 요청이 취소되고 최신 응답만 표시됩니다.

How to Build a React Hook That Handles Sequential Requests


이 정보가 도움이 되었다면 웹 개발에 대한 더 유용한 기사와 도구를 보려면 내 뉴스레터를 구독하세요 . 읽어주셔서 감사합니다!

릴리스 선언문 이 기사는 https://dev.to/zacharylee/how-to-build-a-react-hook-that-handles-series-requests-e49?1에서 복제됩니다.1 침해가 있는 경우, Study_golang@163으로 문의하시기 바랍니다. .com에서 삭제하세요
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3