Effect Hook, Ajax 요청

2023. 5. 31. 23:54IT일기

side effect -> 함수 내에서 어떤 구현이 함수 외부에 영향을 끼치는 경우

ex) 전역 변수 선언으로 상위 선언한 변수가 바뀜

 

순수함수 -> 함수의 입력만이 함수의 결과에 영향을 주는 함수

=> 순수 함수에는 네트워크 요청과 같은 Side Effect가 없음

=> 어떤 전달 인자가 주어져도 항상 동일한 값 리턴

function upper(str) {
  return str.toUpperCase(); // toUpperCase 메소드는 원본을 수정하지 않습니다 (Immutable)
}

upper('hello') // 'HELLO'

React 애플리케이션을 작성할 때에는, AJAX 요청이 필요하거나, LocalStorage 또는 타이머와 같은 React와 상관없는 API를 사용하는 경우가 발생할 수 있음

-> Side Effect를 다루기 위한 Effect Hook 사용

 

useEffect는 컴포넌트 내에서 Side effect를 실행할 수 있게 하는 Hook

useEffect(함수)

-> useEffect의 첫 번째 인자는 함수 -> 해당 함수 내에서 side effect를 실행

 

실행될 때

  • 컴포넌트 생성 후 처음 화면에 렌더링(표시)
  • 컴포넌트에 새로운 props가 전달되며 렌더링
  • 컴포넌트에 상태(state)가 바뀌며 렌더링

=> 매번 새롭게 컴포넌트가 렌더링 될 때 Effect Hook이 실행

Hook을 쓸 때 주의할 점

  • 최상위에서만 Hook을 호출
  • React 함수 내에서 Hook을 호출

 

조건부 effect 발생 (dependency array)

useEffect의 두 번째 인자는 배열

조건을 담은 배열로 조건은 어떤 값의 변경이 일어날 때를 의미, 해당 배열엔 어떤 값의 목록이 들어감

=> 종속성 배열

 

useEffect(함수, [종속성1, 종속성2, ...])

 

useEffect의 두 번째 인자는 종속성 배열

배열 내의 종속성1, 또는 종속성2의 값이 변할 때, 첫 번째 인자의 함수가 실행

배열 내의 어떤 값이 변할 때에만, (effect가 발생하는) 함수가 실행

 

 

단 한 번만 실행되는 Effect 함수

두 번째 배열을 빈 배열[]로 둘 경우

useEffect(함수, [])

=> 빈 배열을 useEffect의 두 번째 인자로 사용하면, 이때에는 컴포넌트가 처음 생성될 때만 effect 함수가 실행

=> 처음 단 한 번, 외부 API를 통해 리소스를 받아오고 더 이상 API 호출이 필요하지 않을 때에 사용

 

useEffect(함수)

=> 컴포넌트가 처음 생성되거나, props가 업데이트되거나, 상태(state)가 업데이트될 때 effect 함수가 실행

 

 

컴포넌트 내에서의 Ajax 요청

목록 내 필터링을 구현

  1. 컴포넌트 내에서 필터링: 전체 목록 데이터를 불러오고, 목록을 검색어로 filter 하는 방법
  2. 컴포넌트 외부에서 필터링: 컴포넌트 외부로 API 요청을 할 때, 필터링한 결과를 받아오는 방법

                                                     장점                                                                              단점

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

 

fetch API 사용

useEffect(() => {
  fetch(`http://서버주소/proverbs?q=${filter}`)
    .then(resp => resp.json())
    .then(result => {
      setProverbs(result);
    });
}, [filter]);

 

로딩화면 구현

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

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

 

fetch 요청의 전후로 setIsLoading을 설정

useEffect(() => {
  setIsLoading(true);
  fetch(`http://서버주소/proverbs?q=${filter}`)
    .then(resp => resp.json())
    .then(result => {
      setProverbs(result);
      setIsLoading(false);
    });
}, [filter]);

'IT일기' 카테고리의 다른 글

UI, UX  (0) 2023.06.13
재귀  (0) 2023.06.09
React state 끌어올리기  (0) 2023.05.31
REST API, Postman  (0) 2023.05.26
HTTP, 네트워크 기초  (0) 2023.05.25