[React] 데이터 흐름의 이해와 비동기 요청 처리

소금·2021년 9월 10일
0
post-thumbnail

Chapter. React에서의 데이터 흐름


🍤 단방향 데이터 흐름

리액터 개발 방식은 페이지 단위가 아닌 컴포넌트 단위로 시작함
컴포넌트를 먼저 만들고, 페이지를 조립해나가는 "상향식"으로 앱을 만듬
=> 테스트가 쉽고 확장성이 좋음
하나의 컴포넌트는 한가지 일만 하기 때문에 트리 구조 형식으로 만들고
데이터를 어디에 둘지 결정함

컴포넌트는 컴포넌트 바깥에서 props를 이용해 데이터를 인자/속성처럼 전달받을 수 있음
=> 데이터를 전달하는 주체는 부모 컴포넌트임
=> 데이터 흐름이 "하향식"임

이벤트에 따라 변할 수 있는 값 = 상태

🍤 state가 아닌것

❌ props를 통해 전달되는 데이터
❌ 시간이 지나도 변하지 않는 값
❌ 컴포넌트 안의 다른 state나 props를 가지고 계산 가능

🍤 state의 위치

하나의 상태를 기반으로 여러 컴포넌트가 영향을 받는다면 공통된 부모 컴포넌트를 찾아 위치

하위 컴포넌트에서의 클릭 이벤트가 부모의 상태를 바꾸어야만 할때, state 끌어올리기 - 상태를 변경시키는 함수를 하위 컴포넌트에 props로 전달 - 하여 해결

Chapter. Effect Hook


🍙 Side Effect

함수 내에서 어떤 구현이 함수 외부에 영향을 끼치는 경우 해당 함수는 side effect가 있음

let salt = "salty!";

function pepper(){
salt = "Now pepper..";
}

pepper(); // 함수 외부의 변수 salt에 영향을 끼쳤음

ex) 타이머 사용 `setTimeout` , 데이터 가져오기 `fetch API`, `localStorage`

>반면 순수 함수는 함수의 입력만이 함수의 결과에 영향을 주는 함수
1)입력으로 전달된 값을 수정하지 않음
2)같은 입력값이 주어졌을 때 언제나 같은 결과값 리턴
3)side effect를 만들지 않음
=> 특정 함수가 다른 함수에 미치는 예기치 못한 영향을 최소화하고,
함수를 만들고 실행할 때 어떤 결과값을 리턴할지 예측할 수 있음

* `Math.ramdom()` 은 입력값이 없지만 호출할 때마다 모두 다른 값을 리턴하므로
=> 순수 함수가 아님

* `fetch API`로 `AJAX`요청을 하는 함수는 자기 자신이 외부 상태 (인터넷 연결 상태, 요청 상태, 서버 상태 등) 에 영향을 받으므로 순수함수가 아님

### 🍙 useEffect

> 컴포넌트 내에서 side effect를 실행할 수 있게하는 hook
`useEffect(실행할 함수, [이 안의 값들이 변경이 일어날 경우 함수 실행] `

1) 인자에 빈 배열 `[]` 넣을 경우
컴포넌트가 처음 생성될때에만 effect 함수 실행
2) 두번째 인자에 아무것도 넣지 않을 경우
아래의 케이스에 따라 함수 실행됨

#### 🍙 useEffect가 실행될때
1) 컴포넌트 생성 후 처음 화면에 렌더링
2) 컴포넌트에 새로운 props가 전달되며 렌더링
3) 컴포넌트에 상태가 바뀌며 렌더링

=> 최상위에서만 hook을 호출하고, react 함수 내에서 호출해야함!

### 컴포넌트 내 AJAX 요청

#### 필터링 구현 시 
1) 컴포넌트 내에서 전체 목록 데이터를 불러오고, 목록을 검색어로 filter
-> http 요청의 빈도를 줄이지만 브라우저의 메모리 상에 많은 데이터를 갖게 되어  클라이언트의 부담이 늘어남
2) 컴포넌트 외부에서 API를 받아오고 필터링한 결과를 받아옴
-> 클라이언트가 필터링 구현을 하지않아도 되지만 빈번한 http요청을 하게 되며 서버의 부담이 늘어남


#### 🍙 AJAX 요청

![](https://velog.velcdn.com/images%2Fcoldbutter%2Fpost%2F5036ab16-c7c4-48a9-b7c0-7b0e31e5deaa%2FZUhsEBnBb-1621827383529.png)

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

// 생략, LoadingIndicator 컴포넌트는 별도로 구현했음을 가정합니다
return {isLoading ? :

로딩 완료 화면
}
//삼항연산자를 써 true일 경우 LoadingIndicator, false일 경우 완료 화면 렌더링
useEffect(() => {
setIsLoading(true);
fetch(http://서버주소/proverbs?q=${filter})
.then(resp => resp.json())
.then(result => {
setProverbs(result);
setIsLoading(false);
});
}, [filter]);
//filter (검색어가 바뀔경우 useEffect안의 함수가 실행됨)
//Proverb state를 받아온 데이터인 result로 바꿔줌

profile
Salty as Salt

0개의 댓글