반동 - 상태를 관리하는 비동기 방식 [ Part 1 ]

이전에는 일부 Recoil 용어와 이를 사용하여 상태를 관리하는 방법에 대한 개요를 살펴보았습니다.

여기서는 Recoil의 비동기적 측면을 살펴보겠습니다.



반동 비동기 상태 관리 지원 -
  • 리액트<Suspense/> . 보류 중인 요청이 완료될 때까지 대체 UI가 렌더링됩니다.
  • React가 없으면<Suspense/> Recoil 후크의 데이터 상태를 사용하여 아직 로드 중인지 완료되었는지 또는 오류가 발생했는지 확인할 수 있습니다.

  • API에서 데이터를 가져와 표시하는 앱을 만들어 보겠습니다.

    시작하려면 새 프로젝트create-react-app를 만들고 새 프로젝트에 맞게 정리한 다음 루트 주위에 래핑<RecoilRoot/>합니다.

    1. 데이터를 가져오는 Selector 작성부터 시작하겠습니다.

    import React from 'react';
    import { selector } from 'recoil';
    
    const url = `https://reqres.in/api/users?page=1`;
    
    const fetchUserDetails = selector({
        key: 'userDetailsSelector',
        get: async ({ get }) => {
            try{
                const response = await fetch(url);
                const data = await response.json();
                return data;
            }catch(error){
                throw error;
            }
        }
    });
    
    function App() {
      return (
        <div> 
            <p> Recoil Example </p>
        </div>
      );
    }
    
    export default App;
    
  • selector를 사용하여 fetch로 데이터를 가져옵니다.
  • async 함수를 get 매개변수로 설정하여 가져온 데이터를 반환합니다.
  • atom의 값을 사용하여 URL 매개변수 또는 사용자 ID, 페이지 번호 및 인증 키와 같은 본문 데이터를 설정할 수 있지만 이번에는 건너뜁니다.

  • 2. <DetailsWithSuspense/>를 구독하고 데이터를 렌더링하는 fetchUserDetails Selector라는 구성 요소를 만듭니다.

    import React from 'react';
    import { selector, useRecoilValue } from 'recoil';
    
    const url = `https://reqres.in/api/users?page=1`;
    
    const fetchUserDetails = selector({
        key: 'userDetailsSelector',
        get: async ({ get }) => {
            try{
                const response = await fetch(url);
                const data = await response.json();
                return data;
            }catch(error){
                throw error;
            }
        }
    });
    
    const DetailsWithSuspense = () => {
        const userDetails = useRecoilValue(fetchUserDetails);
        const { data } = userDetails;
    
        return (
            data.map(item => (
                <div key={item.id}>
                    <p>
         {`Email: ${item.email} Name: ${item.first_name} ${item.last_name}`}. 
                    </p>
                </div>
            ))
        );
    }
    
    
    function App() {
      return (
        <div> 
            <p> Recoil Example </p>
        </div>
      );
    }
    
    export default App;
    
  • 여기서는 useRecoilValue 후크를 사용하여 구독하고 fetchUserDetails Selector 값을 가져옵니다.
  • 그러나 useRecoilState 후크를 사용하여 값을 가져오고 함수를 사용하여 값을 설정할 수도 있습니다. ( 여기에서는 선택기가 반환한 데이터가 읽기 전용이므로 값을 설정할 수 없습니다.)

  • 3. 또한 비동기 데이터를 렌더링하기 위해 <Suspense/>를 추가합시다.

    import React from 'react';
    import { selector, useRecoilValue } from 'recoil';
    
    const url = `https://reqres.in/api/users?page=1`;
    
    const fetchUserDetails = selector({
        key: 'userDetailsSelector',
        get: async ({ get }) => {
            try{
                const response = await fetch(url);
                const data = await response.json();
                return data;
            }catch(error){
                throw error;
            }
        }
    });
    
    const DetailsWithSuspense = () => {
        const userDetails = useRecoilValue(fetchUserDetails);
        const { data } = userDetails;
    
        return (
            data.map(item => (
                <div key={item.id}>
                    <p>
         {`Email: ${item.email} Name: ${item.first_name} ${item.last_name}`}. 
                    </p>
                </div>
            ))
        );
    }
    
    
    function App() {
      return (
        <div> 
            <React.Suspense fallback={<div>Loading...</div>}>
               <DetailsWithSuspense />
            </React.Suspense>
        </div>
      );
    }
    
    export default App;
    
  • 비동기 호출이 완료되거나 오류가 발생할 때까지 <DetailsWithSuspense /> 구성 요소가 렌더링되는 동안 보류 중인 데이터를 처리하는 <Suspense/>fallback를 래핑합니다.
  • 오류 처리 구성 요소를 만들려면 Error Boundaries을 참조하십시오.

  • <서스펜스/>가 마음에 들지 않더라도 리코일이 도와줍니다! 👇



    4. <DetailsWithoutSuspense />를 구독하고 데이터를 렌더링하는 fetchUserDetails Selector라는 또 다른 구성 요소를 만들고 추가합니다.

    import React from 'react';
    import { selector, useRecoilValue, useRecoilValueLoadable } from 'recoil';
    
    const url = `https://reqres.in/api/users?page=1`;
    
    const fetchUserDetails = selector({
        key: 'userDetailsSelector',
        get: async ({ get }) => {
            try{
                const response = await fetch(url);
                const data = await response.json();
                return data;
            }catch(error){
                throw error;
            }
        }
    });
    
    const DetailsWithoutSuspense = () => {
    
        const userDetails = useRecoilValueLoadable(fetchUserDetails);
        const { state } = userDetails;
    
        if (userDetails.state === 'hasError') {
            return <div> There is some problem! </div>
        }
    
        if(state === 'loading'){
            return <div>Its loading</div>
        }
    
        if(state === 'hasValue'){
            const { contents: { data }} = userDetails;
            return (
                data.map(item => (
                    <div key={item.id}>
                        <p>
         {`Email: ${item.email} Name: ${item.first_name} ${item.last_name}`}.   
                       </p>
                    </div>
                ))
            );
    
        }
    }
    
    const DetailsWithSuspense = () => {
        const userDetails = useRecoilValue(fetchUserDetails);
        const { data } = userDetails;
    
        return (
            data.map(item => (
                <div key={item.id}>
                    <p>
         {`Email: ${item.email} Name: ${item.first_name} ${item.last_name}`}. 
                    </p>
                </div>
            ))
        );
    }
    
    
    function App() {
      return (
        <div> 
            <DetailsWithoutSuspense />
            <React.Suspense fallback={<div>Loading...</div>}>
               <DetailsWithSuspense />
            </React.Suspense>
        </div>
      );
    }
    
    export default App;
    
  • 우리는 useRecoilValueLoadable 후크를 사용하여 fetchUserDetails Selector를 구독합니다.

  • 또한 useRecoilValueLoadable는 다음 중 하나일 수 있는 보류 중인 데이터의 현재 상태를 보유하는 state 키가 있는 개체를 반환합니다.

    ㅏ. hasError : 오류 발생 시 설정
    비. loading : 데이터가 보류 중인 경우 설정
    씨. hasValue : 데이터 수신 성공 시 설정
  • state 값에 따라 구성 요소가 적절하게 렌더링될 수 있습니다.
  • state 값이 hasValue 로 설정된 경우 useRecoilValueLoadable에서 반환된 객체는 contents 키에서 보류 중인 데이터를 보유합니다.

  • 이렇게 하면 Recoil API를 사용하여 비동기적으로 데이터를 가져오는 작은 Fetch Data 앱이 완성됩니다. 보다 구조화된 접근 방식을 보려면 아래의 GitHub 리포지토리를 확인하십시오.


    슈브햄크 / 반동 비동기 예제


    Recoil의 비동기적 측면 시도





    다음으로 selectorFamily와 유사하지만 매개변수를 허용하는 selector를 탐색할 것입니다.

    마지막으로 API를 테스트할 수 있게 해준 Reqres에게 감사의 말을 전합니다.

    좋은 웹페이지 즐겨찾기