React 데이터 흐름
React의 개발 방식의 가장 큰 특징은 페이지 단위가 아닌, 컴포넌트 단위로 시작한다는 점이 가장 큰 특징이다.
앱을 만들 때는 상향식으로 만드는 것이 테스트가 쉽고 확장성이 좋다.
하지만, 컴포넌트는 컴포넌트 바깥에서 props를 이용해 데이터를 마치 전달인자(arguments) 혹은 속성(attributes)처럼 전달 받을 수 있다.
데이터를 전달하는 주체는 부모 컴포넌트가 되는데, 이는 데이터 흐름이 하향식임을 의미한다. React는 단방향 데이터 흐름을 따르기 때문에 공통으로 전달하고자 하는 내용이 있다면 부모 컴포넌트에 원하는 내용을 만들고 props를 통해 전달해야 한다.
하지만, 자식 컴포넌트를 이용해 부모의 상태를 변화시켜야 할 때가 있다. 대표적인 예가 새로운 트윗 추가이다.
이를 해결할 수 있는 키워드는 바로 "State 끌어올리기" 이다.
이는 상태를 변경시키는 함수(handler)를 하위 컴포넌트에 props로 전달해서 해결할 수 있다. 콜백함수를 사용하는 것과 비슷하다.
State 끌어올리기 (Lifting State Up)
단방향 데이터 흐름 원칙에 따라, 상위에서 하위 컴포넌트로 전달된 데이터의 형태 혹은 타입이 무엇인지만 알 수 있다.
데이터가 state로 왔는지, 하드코딩으로 입력했는지는 알지 못한다. 그러므로 하위 컴포넌트에서의 어떤 이벤트로 인해 상위 컴포넌트의 상태가 바뀌는 것은 마치 "역방향 데이터 흐름"과 같이 조금 이상하게 들릴 수 있다.
React에서 제시하는 해결책은 상태 끌어올리기이다.
상위 컴포넌트의 "상태를 변경하는 함수" 그 자체를 하위 컴포넌트로 전달하고, 이 함수를 하위 컴포넌트가 실행한다
function ParentComponent() {
const [value, setValue] = useState("초기 값");
const handleChangeValue = (newValue) => {
setValue(newValue);
};
return (
<div>
<div>{value}</div>
<Child handleButtonClick={handleChangeValue} />
</div>
)
};
function ChildComponent({ handleButtonClick }) {
const handleClick = () => {
handleButtonClick('자식이 원하는 값')
}
return (
<button onClick={handleClick}>값 변경</button>
)
}
Effect Hook
Side Effect (부수 효과)
- 함수 내에서 어떤 구현이 외부에 영향을 끼치는 경우 Side Effect가 있다고 이야기한다.
- React에서는 컴포넌트 내에서 fetch를 사용해 API 정보를 가져오거나 이벤트를 활용해 DOM을 직접 조작할 때 Side Effect가 발생했다고 말한다.
Pure Function (순수 함수)
- 오직 함수의 입력만이 함수의 결과에 영향을 주는 함수
- 함수의 입력이 아닌 다른 값이 함수의 결과에 영향을 미치는 경우는 순수 함수가 아니다.
- 입력으로 전달된 값을 수정하지 않는다.
- 어떠한 전달 인자가 주어질 경우, 항상 똑같은 값이 리턴됨을 보장한다(예측 가능한 함수).
React의 함수 컴포넌트
- React의 함수 컴포넌트는, props가 입력으로, JSX Element가 출력으로 나간다. 여기엔 Side Effect가 없고 순수 함수다.
- setTimeout(타이머), fetch API, localStorage 등은 Side Effect를 일으킨다.
useEffect
- useEffect는 컴포넌트 내에서 Side Effect를 실행할 수 있게 하는 Hook이다.
- 브라우저 API를 이용해 타이틀을 변경할 때, 타이머를 만들때, Ajax 요청을 보낼때 사용한다.
- useEffect의 첫 번째 인자는 함수다. 해당 함수 내에서 side effect를 실행하면 된다.
- 컴포넌트 생성 후 처음 화면에 렌더링(표시)
- 컴포넌트에 새로운 props가 전달되며 렌더링
- 컴포넌트에 상태(state)가 바뀌며 렌더링
- 이와 같이 매번 새롭게 컴포넌트가 렌더링 될 때 Effect Hook이 실행된다.
- 최상위에서만 Hook을 호출한다.
- React 함수 내에서 Hook을 호출한다.
- 반복문, 조거문 혹은 중첩된 함수 내에서 호출하지 않는다.
조건부 effect 발생 (dependency array)
useEffect(() => {
console.log(몇 번 호출?)
}) // 무엇인가 업데이트 될 때마다 호출됨
useEffect(() => {
console.log(몇 번 호출?)
},[]) // 컴포넌트가 처음 생성될 때만 함수가 실행
useEffect(() => {
console.log(몇 번 호출?)
},[dep]) // dep이 업데이트 될 떄마다 실행됨
- Dependency Array는 종속성 배열로, useEffect의 두 번째 인자로, Effect hook의 조건을 담은 배열이다.
- 빈 배열 ([])을 넣었을 경우 Effect hook은 컴포넌트가 처음 생성될 때만 실행된다.
- 종속성은 표현식이 아닌 어떤 값으로 할당한다.
- 종속성 배열은 반드시 필요한 값은 아니다. (하지만 적지 않으면 불편함이 발생할 수 있음)
종합퀴즈
- 서로 다른 두 컴포넌트에 하나의 상태가 영향을 준다면, 두 컴포넌트 상위에 상태를 공유하는 컴포넌트가 존재해야 한다.
- React의 데이터는 하향식으로 흐르며, prop로 전달한다.
- Ajax 요청은 외부 상태를 바꾸기 때문에 side effect를 일으킨다.
- React 앱의 가장 작은 단위는 엘리먼트다. 컴포넌트는 이러한 여러 엘리먼트와 함수들이 모여있는 기능적 단위다.
- 컴포넌트도 하나의 엘리먼트다. map함수를 쓸 때 각각의 최상위 엘리먼트들에 key prop이 요구된다.
- Math.random()을 사용할 경우 key가 예상 불가능하며, 시시각각 변하게 된다. 그렇게 되면 React는 많은 컴포넌트 인슽ㄴ스와 DOM 노드를 불필요하게 리렌더링하고, 이에 따라 성능 이슈가 발생하거나 자식 컴포넌트의 state가 유실될 수 있다.
'코드스테이츠 > section2' 카테고리의 다른 글
Web Server 기초 (0) | 2022.06.20 |
---|---|
REST API (0) | 2022.06.10 |
HTTP/네트워크 기초 (0) | 2022.06.10 |
React Props & State (0) | 2022.06.09 |
React SPA (0) | 2022.06.04 |