반응: 사용자 지정 API 후크 작성

우리 모두가 반복해서 작성한 일반적인 API 로직을 처리하기 위해 편리한 사용자 정의 반응 후크를 작성해 보겠습니다.

소개



React에서 몇 년 후, 저는 모범 사례에 대해 다시 교육을 받고 있습니다. 이것은 다음을 의미합니다: Hooks

앱 전체에서 볼 수 있는 매우(매우) 일반적인 흐름 중 하나는 API에서 데이터를 로드하고 표시하는 것입니다.

일반적으로 다음과 같이 보입니다.



이것은 매우 복잡한 구성 요소를 초래하는 경향이 있습니다. 이 문제를 해결하기 위해 새로 발견한 후크 지식을 사용합시다.

후크 디자인하기



위에서 설명한 흐름을 기반으로 후크에서 제공할 데이터를 정의하는 것은 매우 쉽습니다. 반환됩니다:
  • 응답 데이터
  • 로딩 플래그
  • 오류(성공 시 null)
  • 재시도 방법

  • 요청 코드를 서비스 클래스에 위임하는 것을 여전히 고맙게 생각한다는 점을 감안할 때 후크가 서비스를 호출하도록 하는 것이 좋습니다.

    다음 사용법으로 이어집니다.

    const [ user, isLoading, error, retry ] = useAPI('loadUserById', 56);
    

    API 서비스 준비



    우리의 아름다운 ajax 코드를 모두 넣을 수 있는 작은 서비스 클래스를 사용합시다.

    class APIService {
        async loadUsers() {
            // ... ajax magic
        }
    
        async loadUserById(id) {
            // ... ajax magic
        }
    } 
    
    export default new APIService();
    

    후크 작성



    여기서 우리의 목표는 표준 반응 후크를 결합하여 모든 필수 필드를 생성하는 것입니다.

    상태



    React는 이미 상태 속성을 생성하고 업데이트하기 위한 useState 후크를 제공합니다.

    필드를 생성해 보겠습니다.

    function useAPI(method, ...params) { 
    
      const [data, setData]           = useState(null);
      const [isLoading, setIsLoading] = useState(false);
      const [error, onError]          = useState(null);
    
    }
    

    서비스 호출



    여기에서 작동하는 React 후크는 useEffect 입니다. 여기서 비동기 코드를 실행할 수 있습니다.

    useEffect(() => {
       // ... async code
    }, []);
    

    그러나 후크가 retry 메서드를 반환하기로 결정했습니다. 따라서 비동기 코드를 자체 함수로 이동해 보겠습니다.

    const fetchData = async () => {
       // ... async code
    }
    
    useEffect(() => { fetchData() }, []);
    

    이제 후크의 인수를 기반으로 올바른 서비스 메서드를 호출해 보겠습니다.

    const fetchData = async () => {
      // Clear previous errors
      onError(null);
    
      try {
        // Start loading indicator
        setIsLoading(true);
    
        // Fetch and set data
        setData(await APIService[method](...params));
      } catch (e) {
        // Set the error message in case of failure
        setError(e);
      } finally {
        // Clear loading indicator
        setIsLoading(false);
      }
    };
    
    useEffect(() => { fetchData() }, []);
    

    결과



    그리고 짜잔! 후크를 사용할 준비가 되었습니다.

    function useAPI(method, ...params) {
        // ---- State
        const [data, setData]           = useState(null);
        const [isLoading, setIsLoading] = useState(false);
        const [error, setError]         = useState(null);
    
        // ---- API
        const fetchData = async () => {
          onError(null);
          try {
            setIsLoading(true);
            setData(await APIService[method](...params));
          } catch (e) {
            setError(e);
          } finally {
            setIsLoading(false);
          }
        };
    
        useEffect(() => { fetchData() }, []);
    
        return [ data, isLoading, error, fetchData ];
    }
    

    구성 요소에서 사용



    컴포넌트에서 사용하는 방법에 대한 간단한 예를 작성해 보겠습니다.

    function HomeScreen() {
      const [ users, isLoading, error, retry ] = useAPI('loadUsers');
    
      // --- Display error
      if (error) {
        return <ErrorPopup msg={error.message} retryCb={retry}></ErrorPopup>
      }
    
      // --- Template
      return (
        <View>
          <LoadingSpinner loading={isLoading}></LoadingSpinner>
          {
              (users && users.length > 0) &&
                <UserList users={users}></UserList>
          }
        </View>
      );
    }
    

    결론



    응용 프로그램 전체에서 공통 코드를 다시 작성하지 않는 방법에는 여러 가지가 있습니다.

    과거에 나는 종종 그 중 일부를 Store 에 위임하거나 Mixins 사용할 준비가 된 모든 논리로 구성 요소를 생성하는 데 사용했습니다.

    사용자 정의 후크는 우리에게 완전히 새로운 풍미를 제공하고 문제를 처리하기 위한 새로운 전략을 열어줍니다.

    관행의 발전을 목격하게 되어 기쁩니다.

    건배,

    패트릭

    좋은 웹페이지 즐겨찾기