본문 바로가기

개념/React

[React] 컴포넌트 내에서 ajax 요청하기, loading indicator 추가하기

🦋 시작하며

useEffect 기본을 이해해야 한다. (링크)


📡 필터링 예제로 보는 ajax 요청

 

어떤 목록을 필터링하는 예제에서 두가지 방법이 있을 수 있다.

  1. 컴포넌트 내에서 필터링: 처음에 한번 외부 API로부터 전체 목록 데이터를 불러오고, 목록을 검색어로 filter 하는 방법 (코드펜 예제)
  2. 컴포넌트 외부에서 필터링: 한번에 다 받아오지 않고 검색어 바뀔 때마다, 컴포넌트 외부로 API 요청해 필터링 한 결과를 받아오는 방법 (보통, 서버에 매번 검색어와 함께 요청하는 경우가 이에 해당) (코드펜 예제)

각각의 장단점은 아래와 같다.

  장점 단점
컴포넌트 내부에서 처리 HTTP 요청의 빈도를 줄일 수 있다 브라우저(클라이언트)의 메모리 상에 많은 데이터를 갖게 되므로, 클라이언트의 부담이 늘어난다
컴포넌트 외부에서 처리 클라이언트가 필터링 구현을 생각하지 않아도 된다 빈번한 HTTP 요청이 일어나게 되며, 서버가 필터링을 처리하므로 서버가 부담을 가져간다

💡 Loading Indicator를 포함해서 ajax요청보내기

로딩이 길어질 때를 대비하여 UI적으로 클라이언트를 고려한 장치들을 넣어주는데

이때 들어가는 것들엔 loading indicator나 loading placeholder가 있다.

이것들에 더 알고 싶다면 아래의 더보기 클릭!

 

--------

더보기

사용자에게 로딩중을 표현하는 방식으론 loading indicator나 loading placeholder가 있다.

좌) loading indicator    우)loading placeholder

loading indicator는 아이콘으로 로딩중을 표현하는 것이고,

loading placeholder는 다른 말로 *스켈레톤 UI라고도 부르는데, 컨텐츠의 윤곽을 나타내주는 애니메이션으로 어디에 뭐가 나오겠구나 대충 예상가능하게 보여주는 것이다. netflix나 youtube를 들어가면 로딩장면에서 볼 수 있다.

개인적으로 이걸보면서 저런건 어떻게 한건가 싶었는데,

이를 구현하는 module이 npm에 있었다. 바로 placeholder-module

기회가 될때 이걸 사용해 봐야겠다.

 

*스켈레톤 UI:  실제 데이터가 렌더링 되기 전, 보일 화면의 윤곽을 먼저 그려주는 로딩 애니메이션.

--------

 

fetch를 이용하여 서버에 필요한 ajax요청을 보낼 수 있다.

fetch는 외부로부터 어떤 데이터가 돌아올지 보장이 되지 않는 side effect함수이므로 

React의 useEffect hook을 사용한다.

function LoadingIndicator() {
  return (
    <img
      className="loading-indicator"
      alt="now loading..."
      src="loading.gif"
      style={{ margin: '1rem' }}
    />
  );
}

export default LoadingIndicator;
import LoadingIndicator from './component/LoadingIndicator';

const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
  setIsLoading(true); //로딩상태 기본적으로 true로 리셋후
  fetch(`http://서버주소/proverbs?q=${filter}`)
    .then(resp => resp.json())
    .then(result => {
      setProverbs(result); //결과를 받아서 실행시킬 함수
      setIsLoading(false); //결과 받고나서 로딩상태 false로 바꿔주기
    });
}, [filter]);

// 생략, LoadingIndicator 컴포넌트는 별도로 구현했음을 가정합니다
return {isLoading ? <LoadingIndicator /> : <div>로딩 완료 화면</div>}

손 = loading indicator