React Data Flow
React Effect Hook
useEffect()
컴포넌트 내에서 Ajax 요청
리엑트는 "단방향 데이터 흐름(one-way data flow)" 이라는 특징을 가지고 있다.
부모 컴포넌트가 자식 컴포넌트에게 Props 를 이용하여 데이터를 전달한다.
그런데 부모 컴포넌트의 상태가 하위 컴포넌트에 의해 변하는 상황도 존재한다.
이럴 경우 상태 끌어올리기(lifting state up) 을 해야 한다.
부모 컴포넌트에서 상태를 변경시키는 함수(setState()
를 넣은 함수)를 만들어 props를 통해 자식 컴포넌트에 전달하면, 하위 컴포넌트가 이 함수를 실행한다. 마치 콜백 사용과 비슷하다.
function Parent() {
const [state, setState] = useState(false);
// state를 변경하는 함수 만듦
const handleChangeValue = value => {
setState(value);
}
// children 에 함수를 전달
return (
<div>
<Children handleButtonClick={handleChangeValue} />
</div>
)
}
프로그래밍에서 side effect 는 함수가 자신의 외부에 영향을 끼치는 경우 "함수가 side effect 를 발생시킨다" 라고 한다.
순수 함수는...
수학에서 정의하는 '함수' 와 비슷하다
Math.random()
은 순수함수가 아니다 - 1. 동일한 입력에 동일한 결과를 내지 않는다.React의 함수 컴포넌트는 props가 입력으로, JSX Element가 출력으로 나간다. 여기에는 그 어떤 Side Effect도 없으며, 순수 함수로 작동한다.
하지만 보통 React 애플리케이션을 작성할 때에는, AJAX 요청이 필요하거나, LocalStorage 또는 타이머와 같은 React와 상관없는 API를 사용하는 경우가 발생할 수 있다. 이는 React의 입장에서는 전부 Side Effect 이다.
document.title
사용 하여 <title>
변경 등)React 와 상관없는 API 를 사용하면 side effect 이며, Effect Hook 을 사용하여야 한다.
React 에서 useEffect
는 컴포넌트 내에서 side effect (fetch, setTimeout, LocalStorage 등) 를 실행할 수 있게 하는 Hook 이다.
useEffect
는 컴포넌트 안에 작성한다.
useEffect(function [, depencency 1, depencency 2, ...])
Parameters:
1.function
- 실행할 함수
2.dependencies
- 종속될 요소 배열 (dependency array) [optional]
Parameters 설명:
실행할 함수: function
인자에 annonymous function 을 넣고 그 안에 실행할 side effect 를 적어주면 된다.
종속될 요소 배열: 종속성 배열 내의 값이 변경이 일어날 때만 useEffect
의 실행할 함수가 호출되게 만들 수 있다. 그래서 배열 안에는 변화가 일어나는 state 변수들을 넣어준다.
종속될 요소 배열 인자 | useEffect() callback 작동 |
---|---|
없음 | 매번 자신이 위치한 컴포넌트가 렌더링 될 때 실행 |
빈 배열 ([] ) | 컴포넌트 최초 생성 시에만 한번 실행되고 다시 실행되지 않음 |
배열 | 종속성 배열 내의 값이 변경이 일어날 때만 실행 |
컴포넌트는 다음 경우 렌더링된다(이때 useEffect 의 함수가 호출된다):
https://reactjs.org/docs/hooks-rules.html
서버 요청(fetch)은 side effect 를 일으키는 동작이기 때문에, React component 에서 AJAX 요청을 하려면 useEffect()
안에 fetch
를 쓴다.
useEffect(() => {
fetch(`http://address.com/method?parameter=value)
.then(resp => resp.json())
.then(result => {...});
}, [filter]);
입력창을 통한 목록 필터링을 구현하기 위해 다음 두가지의 접근이 있을 수 있다:
컴포넌트 내부에서 필터링:
전체 목록 데이터를 불러오고, 목록을 검색어로 필터
컴포넌트 외부에서 필터링:
컴포넌트 외부로 API 요청을 할 때에, 필터링한 결과를 받아옴.
(보통 서버에 매번 검색어와 함께 요청하는 경우)
장점 | 단점 | |
---|---|---|
컴포넌트 내부에서 처리 | HTTP 요청의 빈도를 줄일 수 있다. | 브라우저의 메모리 상에 많은 데이터를 갖게 되므로 클라이언트의 부담이 늘어난다. |
컴포넌트 외부에서 처리 | 클라이언트의 부담이 줄어든다. | HTTP 요청이 늘어나며, 서버의 부담이 늘어난다. |
상용 어플리케이션은 클라이언트와 서버의 부담을 적절히 분배하여 설계한다.
Ajax 요청이 느릴 경우에는 로딩 화면(loading indicator)을 사용한다.
Debouncing and Throttling Explained Through Examples | CSS-Tricks