본문 바로가기

Programming/React ; Redux

React Async 사용하기 - 1. useAsync, Helper components

React Async는 promise resolution, data fetching을 위한 유틸리티이다. 

React Component와 여러 가지 Hook을 제공해주며 fetch api, Axios, GraphQL 등을 지원한다. 

 

React Async가 제공하는 3가지의 메인 API

  • hook : useAsync
  • component : Async 
  • factory function : createInstance

 


1. hok - useAsync 

const state = useAsync(options);

옵션은 되도록 inline object literal로 작성하고, state의 프로퍼티는 비구조화해서 사용하는 것을 추천한다. 

 

import { useAsync } from 'react-async'; 

// 비동기 데이터 요청 
const loadPlayer = async({ playerId }, { signal }) => {
  const res = await fetch(`/api/players/${playerId}`, { signal }); 
  if ( !res.ok ) throw new Error(res.statusText);
  return res.json(); 
}

// 컴포넌트 
const MyComponent = () => {
  const { data, error, isPending } = useAsync({ promiseFn: loadPlayer, playerId: 1 }); 
  if ( isPending ) return "Loading..."; 
  if ( error ) return `Something went wrong: ${error.message}`; 
  
  // 데이터가 있을 경우 Rendering; 
  if ( data ) {
    return (
      <div>
        <strong>Player data:</strong>
        <pre>{JSON.stringify(data, null, 2)}</pre>
      </div>
    );
  }
  return null;
}

또는

const MyComponent = () => {
  const { data, error, isPending } = useAsync(loadPlayer, options); 
  // ...
}

위의 방식대로 코드를 작성하면 리턴값에 따라 if문으로 분기를 쳐서 반환하는 컴포넌트가 달라진다. helper component를 사용하면 좀 더 가독성 있게 코드를 작성할 수 있다.

 

아래는 helper component를 적용한 예시이다. 

프로미스 객체의 반환값을 좀 더 명시적으로 표현해서, 비동기 데이터 조회 시 화면을 좀 더 풍성하게 만들 수 있도록 해준다.

import { useAsync } from 'react-async'; 

// 비동기 데이터 요청 
const loadPlayer = async({ playerId }, { signal }) => {
  const res = await fetch(`/api/players/${playerId}`, { signal }); 
  if ( !res.ok ) throw new Error(res.statusText);
  return res.json(); 
}

// 컴포넌트 
const MyComponent = () => {
  const state = useAsync({ promiseFn: loadPlayer, playerId: 1 }); 
  return (
    <>
     <IfInitial state={state}>not yet...</IfInitial> 
     <IfPending state={state}>Loading...</IfPending> 
     <IfRejected state={state}>{error => `Something went wrong: ${error.message}`}</IfRejected>
     <IfFulfilled state={state}>
        {data => (
          <div>
            <strong>Player data:</strong>
            <pre>{JSON.stringify(data, null, 2)}</pre>
          </div>
        )}
      </IfFulfilled>
    </>
  );
}

useAsync를 적용해서 아래와 같이 select box를 만들어보았다.

            <FormGroup>
              <Label for="theme">대시보드 테마</Label>
              <Input type="select" name="select" id="theme">
                <option>선택</option>
                <IfFulfilled state={categories}>
                  {data =>
                    data.data.map(item => (
                      <option key={item.code} value={item.code}>
                        {item.label}
                      </option>
                    ))
                  }
                </IfFulfilled>
              </Input>
            </FormGroup>

'Programming > React ; Redux' 카테고리의 다른 글

JSX란?  (0) 2021.05.21
State 특성 3가지  (0) 2021.05.21
React/Redux - 실수 모음집 (누적 중)  (0) 2021.05.15
React.memo 사용 예제  (0) 2021.05.10
[Reactstrap] Modal 컴포넌트 CSS 수정하기  (0) 2021.05.07