- Side effect가 어떤 의미인지 알 수 있다.
- React 컴포넌트를 만들 때 side effect로부터 분리해서 생각할 수 있다.
- Side effect의 예를 들 수 있다.
- Effect Hook을 이용해 비동기 호출 및 AJAX 요청과 같은 side effect를 React 컴포넌트 내에서 처리할 수 있다.
- Effect Hook에서의 dependency array 사용법을 이해할 수 있다.
- 컴포넌트 내에서 네트워크 요청 시, 로딩 화면과 같이 보다 나은 UI를 만드는 법을 이해할 수 있다.
side effect란? 부수효과
함수 내에서 어떤 구현이 함수 외부에 영향을 끼치는 경우 해당 함수는 Side Effect가 있다고한다.
리액트에서는 컴포넌트 내에서 fetch를 사용해
API 정보를 가져오거나 이벤트를 활용해 돔을 직접 조작할때 Side Effect가 발생했다고 한다.
Side Effect란 React 컴포넌트가 화면에 렌더링 된 후에 비동기로 처리되어야 하는 부수적인 효과들
API를 사용해서 외부에서 데이터를 비동기적으로 가져올 때
화면을 먼저 렌더링하고 실제 데이터는 비동기로 가져오는것이 권장된다.
요청 즉시 1차 렌더링을 하고
연동하는 api응답이 늦어지거나 응답이 없을 경우에도 영향을 최소화 할 수 있어서 사용자 경험 측면에서 유리하다 (출처)
Pure Function 순수함수?
오직 함수의 입력만이 함수의 결과에 영향을 주는 함수.
입력이 아닌 다른 값이 함수의 결과에 영향을 미치는 경우 순수함수라고 부를 수 없다.
입력으로 전달된 값을 수정하지 않는다.
순수 함수에는 네트워크 요청과 같은 Side Effect가 없다.
어떠한 전달 인자가 주어질 경우 항상 똑같은 값이 리턴됨을 보장한다.
Math.random()은 항상 다른값이 리턴되기 때문에 순수함수라 볼 수 없다.
fetch API 를 이용해 AJAX요청을 한다고 가정했을때 순수함수가 아닌이유?
네트워크,서버 상황에 따라 다른 응답을 할 수 있기 때문에 예측 불가능하므로 아니다.
React 함수 컴포넌트
React의 함수 컴포넌트는
입력이 props
출력 JSX Element
어떤 side effect가 없고 순수함수이다.
부모 컴포넌트에서 자식 컴포넌트로 데이터를 넘겨주고
자식컴포넌트는 입력으로 전달된 값을 수정하지 않는다.
하지만? 보통 리액트 어플리케이션 작성할때
AJAX 요청이 필요하거나 리액트와 상관없는 API 사용하는 경우가 발생할 수 있다.
리액트에서는 이모든것이 Side Effect
이걸 또...따로 다뤄주기 위해 Effect Hook 사용...
React 컴포넌트에서의 Side Effect
✔️ 타이머 사용(setTimeout)
✔️ 데이터 가져오기(fetch API, localStorage)
Effect Hook
: 컴포넌트 내에서 Side effect를 실행할 수 있게 하는 Hook
여기서 Side effect는 브라우저 API를 이용하여, 타이틀을 변경한것.
useEffect(함수)
1️⃣ 첫 번째 인자는 함수
함수 내에서 side effect를 실행하면 된다.
언제 실행 되느냐?
1. 컴포넌트 생성 후 처음 화면에 렌더링(표시)
2. 컴포넌트에 새로운 props가 전달되며 렌더링
3. 컴포넌트에 상태(state)가 바뀌며 렌더링
매번 새롭게 컴포넌트가 렌더링 될때 effect hook이 실행된다.
⚠️훅을 쓸때 주의할 점
1. 최상위에서만 호출
2. 리액트 함수 내에서 호출
2️⃣ 두번째 인자는 배열
이 배열에는 조건이 담겨있다.
boolean 형태의 표현식이 아닌 어떤 값의 변경이 일어날 때를 의미
따라서 해당 배열에는 어떤 값의 목록이 들어간다. => 종속성 배열
위 예제에서는 세 상태가 존재한다.
1. 명언 목록(proverbs)
2. 필터링할 문자열(effect)
3. 카운트(count)
filter가 변할 때에만, effect 함수가 실행된다.
카운트 올리는 버튼은 상태가 바뀌지만 effect함수는 실행되지 않는다.
이유는 종속성 배열에는 filter만 존재하고 count는 존재하지 않기 때문이다.
🔍 카운트 버튼을 눌렀을 때에도 effect 함수를 실행시키려면?
버튼에 있는 상태변수를 efftct함수의 두번째 인자인 종속성 배열에 넣어준다.
해당 배열의 값이 변화할때마다 effect함수가 실행되기 때문이다.
API
useEffect(함수, [종속성1, 종속성2, ...])
useEffect의 두 번째 인자는 위에서 살펴보았듯이 종속성 배열이다.
배열 내의 종속성1, 또는 종속성2의 값이 변할 때, 첫 번째 인자의 함수가 실행된다.
즉 배열내의 어떤값이 변할 때에만, effect가 발생하는 함수가 실행된다.
단 한번만 실행되는 Effect 함수
만약 종속성 목록에 아무런 종속성도 없다면?
즉 두번째 배열을 빈배열로 둘 경우 두 번째 인자를 아예 안 넘기는것과 어떻게 다를까?
1. 빈 배열넣기
useEffect(함수, [])
useEffect(()=>{
console.log("hihi")
})
2. 아무것도 넣지 않기(기본 형태)
useEffect(함수)
useEffect(()=>{
console.log("hihi")
},[])
2번 기본형태의 useEffect는
1. 컴포넌트가 처음 생성되거나
2. props가 업데이트되거나
3. 상태(state)가 업데이트 될 때 effect 함수가 실행됨
1번은 컴포넌트가 처음 생성될 때 단 한번 effect함수가 실행된다.
외부에서 API를 통해 리소스를 받아오고 더 이상 API호출이 필요하지 않을 때 사용한다.
useEffect(()=>{
console.log("hihi")
},[dep])
// dep이 업데이트 될 때마다 실행된다
Data Fetching
목록 내 필터링을 구현하기 위해서는
1. 컴포넌트 내에서 필터링 : 전체 목록 데이터를 불러오고, 목록을 검색어로 filter함수사용
2. 컴포넌트 외부에서 필터링 :
컴포넌트 외부로 API요청을 할 때, 필터링한 결과를 받아오는 방법
검색어가 바뀔 때마다 외부 API를 호출
장점 | 단점 | |
내부에서 처리 | HTTP 요청 빈도 줄일 수 있음 | 브라우저(클라이언트)의 메모리상에 많은 데이터를 갖게되어서 클라이언트의 부담이 커짐 |
외부에서 처리 | 클라이언트가 필터링 구현을 생각하지 않아도 된다 | 빈번한 HTTP 요청이 일어나게 되며, 서버가 필터링 처리를 하므로 서버 부담 커짐 |
AJAX 요청
AJAX는 화면 전체를 새로 랜더링 할 필요 없이 필요한 부분만 비동기적으로 서버에서 데이터를 받아와서 업데이트 할 수있다.
useEffect(()=>{
fetch(`http://서버주소/proverbs?q=${filter}`)
.then(resp => resp.json())
.then(result => {
setProberbs(result);
});
},[filter]);
AJAX 요청이 느릴경우
외부 API접속이 느릴 경우를 고려하여 로딩화면(loading indicator)구현은 필수적이다.
구현하는 방법 => 상태처리필요
const [isLoading, setIsLoading] = useState(true);
return {isLoading ? <LoadingIndicator /> : <div>로딩 완료 화면</div>}
fetch 요청의 전후로 setIsLoading을 설정해주어 보다 나은 UX 구현 할 수 있다.
useEffect(()=>{
setIsLoading(true);
fetch(`http://서버주소/proverbs?q=${filter}`)
.then(resp => resp.json())
.then(result => {
setProberbs(result);
setIsLoading(false);
});
},[filter]);
'React' 카테고리의 다른 글
리액트로 모달창,토글,탭,태그 구현 (0) | 2023.04.19 |
---|---|
useEffect훅을 사용해 과제를 풀어보았다. (0) | 2023.04.03 |
[React] 데이터 흐름과 state끌어올리기 (Lifting State Up) (2) | 2023.03.31 |
[React] 모달창 만들기 (2) | 2023.03.27 |
React Twittler Intro (4) | 2023.03.22 |