210906-210907 CodeStates 36-37일차

공윤배·2021년 9월 22일
0

210906-210907 CodeStates 36-37일차

이틀간 리액트의 단방향 데이터흐름이 무엇인지, 단방향 데이터흐름의 원칙을 지키면서 state를 끌어올리는 방법, 컴포넌트가 렌더링될때마다 특정작업을 실행시킬수 있는 Effect Hook에 대해 공부하고, 간단한 웹페이지를 이용한 실습을 했다.

React의 데이터 흐름

React의 특징 중 하나는 컴포넌트 단위로 개발한다는 점이다.
하나의 페이지를 만들기 위해서는 여러개의 컴포넌트들로 나누어 컴포넌트들을 조합하여 페이지를 만드는 방식으로 개발한다.
컴포넌트들을 조합할 때 트리구조를 이루며 조합하는데 이때 컴포넌트들간의 부모자식관계가 성립된다.
이전에 React를 처음으로 배우면서 props와 state에 관하여 공부했었다.
props는 상위 컴포넌트로부터 전달받은 값이며 컴포넌트 내에서 임의로 변경될 수 없는 데이터이다.
state는 컴포넌트내에서 관리되는 시간이 흐름에 따라 변할 수 있는 데이터이며 state가 변경됨을 감지하면 웹페이지에서 해당 컴포넌트만 부분적으로 리렌더링된다.

props를 전달받을 때 상위컴포넌트에서 전달받는데, 부모 컴포넌트에서 자식컴포넌트로만 데이터 전달이 가능하다.(자식컴포넌트에서 부모컴포넌트로 데이터 전달은 불가능하다.)
이를 React의 단방향 데이터흐름이라 한다.(하향식)

State끌어올리기

state는 변할 수 있는 값으로 컴포넌트내에서 관리되는 데이터이다.

React를 이용해 다음과 같은 페이지를 만들기 위해서는 일단 페이지를 컴포넌트로 분리해야한다.


위와 같이 새로운 트윗을 작성하는 NewTweet컴포넌트, 트윗의 목록을 보여주는 Tweets컴포넌트, 트윗개별의 내용을 보여주는 Tweet컴포넌트로 분리할 수 있다.
이러한 페이지를 만들기 위해서는 트윗들의 내용을 담는 데이터(tweetList)가 필요할 것이다.
NewTweet컴포넌트를 이용해 새로운 트윗을 추가해야하는 기능이 있으므로 tweetList는 변할 수 있어야한다.(props가 아닌 state여야한다.)

NewTweet컴포넌트는 tweetList에 새로운 트윗을 저장할 수 있어야 하고, Tweets컴포넌트는 tweetList의 내용들을 각각의 Tweet컴포넌트에 전달하여 페이지에 보여줄 수 있어야한다.
리액트의 데이터 단방향 흐름(위에서 아래로만 전달) 때문에 tweetList는 NewTweet컴포넌트와 Tweets컴포넌트의 공통된 부모컴포넌트 App컴포넌트에서 관리되어야 할 것이다.

Tweets컴포넌트는 props로 tweetList를 전달받아 트윗의 내용들을 보여주고 NewTweet컴포넌트는 state갱신함수 setTweetList를 전달받아 컴포넌트 오른쪽에 위치한 '새글쓰기'버튼이 클릭되면(Onclick이벤트) setTweetList함수를 이용해 App컴포넌트에서 관리되는 state인 tweetList를 갱신할 수 있다.

이와 같이 상위 컴포넌트의 state값을 하위 컴포넌트에서 수정하여 상위컴포넌트로 올려주는 것이 state끌어올리기(Lifting state)이다.

React의 데이터흐름은 오로지 위에서 아래방향으로만 가능하며(props를 통해 전달), 만일 자식 컴포넌트에서 상위 컴포넌트에서 관리되는 state를 수정해야 한다면 props로 갱신함수를 전달받아 이벤트를 이용해 state를 갱신해야한다.

Effect Hook

Side Effect와 순수함수

Side Effect란 함수가 실행되면서 함수 외부에 존재하는 값이나 상태를 변경시키는 등의 행위를 말한다.
정차형 프로그래밍에서는 흔히 존재하는 작업이고, 무조건적으로 나쁘다고 볼수는 없지만 최근에는 Side Effect는 프로그램을 읽기 어렵게 하고, 실행상태를 예측하기 어렵게 하여 점점 Side Effect를 최소화하는 방향으로 변하고 있다.
함수가 전달받은 매개변수를 통해 연산을 수행하고 결과를 반환할때, 그 결과는 항상 일관되고 예측할 수 있어야(side Effect가 없어야 가능하다.) 프로그램이 쉽고 단순해지며, 유지보수가 쉬워지기 때문이다.

(1)같은 입력값이 주어질때, 같은 결과값을 반환하고, (2)side-Effect를 가지지 않는 함수를 순수함수라고 한다.

React의 함수컴포넌트는 props를 입력받아 JSX Element를 반환하는 순수함수로 작동해야한다.
하지만 React를 이용하여 애플리케이션을 개발할 때, AJAX요청이나, 외부의 API를 사용해야하는 경우가 필요할 수 있는데, 이처럼 React에서 컨트롤 하지못하는 외부요소와 상호작용을 하는 모든 행위가 React입장에서는 Side Effect이다.

이러한 Side Effect들을 관리하기 위해 useEffect를 사용할 수 있다.

useEffect

useEffect함수는 React컴포넌트가 렌더링 될 때마다 특정작업을 실행할 수 있도록 하는 Hook이다.(class Component의 lifecycle API기능을 사용가능하게 해준다.)
useEffect함수의 첫번째 인자는 함수,두번째 인자로는 배열을 가질수 있다.
useEffect의 첫번째 인자로 전달되는 함수는 effect라고 부르며 컴포넌트가 렌더링 될때마다 (컴포넌트가 생성될때, state가 변경되었을때, 새로운 props를 전달받았을때) 실행된다.
useEffect의 두번째 인자로 전달되는 배열은 종속성 배열로, useEffect의 조건부 실행을 가능하게 해준다.
배열내의 종속성 값(종속성 배열안에 적어둔 state,props)이 변할때만 effect를 실행하게끔 해준다.

종속성 배열을 적지 않는다면(useEffect함수에 함수인자 하나만 전달한다면), effect는 컴포넌트가 생성될때 실행되고, 이후에는 컴포넌트가 렌더링될때마다 실행된다.(componentDidMount,componentDidUpdate)
종속성 배열을 빈배열[]로 전달하면, 최초로 컴포넌트가 생성될때만 effect가 실행된다.(componentDidMount)
effect의 리턴값으로 함수를 지정하면 컴포넌트가 삭제될때 실행하는 effect로 사용할 수 있다.(componentWillUnmount)
이를 cleanup함수라고한다.

위 사진은 리액트 effectHook문서의 코드로 effect함수는 cleanup이라는 함수를 반환한다.

ChatAPI.subscribeToFriendStatus함수는 종속성배열이 없으므로 컴포넌트가 생성될때(componentDidMount)와 업데이트 될때마다(componentDidUpdate) 실행될 것이다.
effect함수가 반환하는 cleanup함수는 컴포넌트가 삭제될때(componentWillUnmount) 실행될 것이다.

0개의 댓글