상태상태 안상태
React 는 컴포넌트 단위로 기능 개발을 구현하는 라이브러리이다.
컴포넌트는 단일 책임원칙에 따라 기능별로 쪼개서 한 컴포넌트가 한가지 일만 하도록 개발하는 것이 좋다.
웹 페이지를 만들기전 구상을 할때 부터 각 기능별 컴포넌트로 나누는 설계를 한다.
이렇게 설계를 하게 되면 트리형태의 컴포넌트 구조를 갖게 되는데
가장 상위 컴포넌트부터 개발을 시작할 수도 있고 하위 컴포넌트 부터 상위컴포넌트로 올라가면서 개발을 할 수도 있다.
컴포넌트 설계가 끝나면 이제 데이터를 어디에 둘 지 결정해야하는데 데이터는 props
를 통해 상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달할 수 있다.
데이터를 전달해 주체는 상위 컴포넌트이고, 하위 컴포넌트는 상위 컴포넌트로 데이터를 전달 할 수 없다.
즉, React의 데이터의 흐름은 하향식(top-down)임을 의미한다.
React는 무적권 단방향 데이터 흐름을 따른다!! 데이터가 하향식으로만 흐른다는 말이다!!
State(상태) 는 특정 컴포넌트에서만 유의미 하다면 해당 컴포넌트에 두면 되지만
만약 하나의 상태가 두개 이상의 컴포넌트에 영향을 미친다면 어느 컴포넌트에 상태를 두어야 할까? 🤔
이런경우에는 영향을 미치는 컴포넌트들을 아우르는 상위 컴포넌트에 상태를 두면 된다.
우선 데이터는 단방향 하향식으로 흐른다고 했다. 하지만 상태를 상위 컴포넌트에 배치하고 나서
하위 컴포넌트에서 이벤트를 사용함에따라 상위 컴포넌트 상태의 변경이 필요한 상황들이 종종 있다.
예를 들면 게시판 리스트 상태는 상위 컴포넌트에 놔두고 질문등록을 구현한 하위 컴포넌트를 둔다고 했을때 하위 컴포넌트의 질문 등록하기 버튼을 클릭하면 상위 컴포넌트의 게시판 리스트에 등록한 질문이 추가 되어야 하는 상황
이는 마치 역방향(하위 ---> 상위)으로 데이터 흐름이 이동하는 것 처럼 보인다.
이를 해결하기 위해서 React는 State 끌어올리기
라는 해결책을 제시했다.
상위 컴포넌트에서 상태를 변경시키는 함수를
하위 컴포넌트에 props
로 전달해서 사용할 수 있다.
마치 콜백함수를 사용하는 것과 비슷하다.
import React, { useState } from "react";
export default function ParentComponent() {
const [value, setValue] = useState("Hello");
const handleChangeValue = () => {
setValue("BYE");
};
return (
<div>
<div>값 : {value} </div>
<ChildComponent onBut={handleChangeValue} />
</div>
);
}
function ChildComponent({ onBut }) {
const handleClick = () => {
// 이 버튼을 눌러서 부모의 상태를 바꿀 순 없을까?
onBut();
};
return <button onClick={handleClick}>값 변경</button>;
}
상위 컴포넌트 ParentComponent()
하위 컴포넌트 ChildComponent({ onBut })
하위 컴포넌트에서 클릭이벤트를 수행할 시 상위 컴포넌트의 상태를 변경시킬려면
- 상위 컴포넌트의 상태를 변경시키는 함수를 하위 컴포넌트의
props
로 전달!
<ChildComponent onBut={handleChangeValue} />
- 하위컴포넌트에서 전달인자로
props
값을 받아서 이벤트핸들러 내에서 호출시켜 해당 이벤트를 수행할 시 상태를 변경시키는 함수를 호출하게 함.const handleClick = () => { // 이 버튼을 눌러서 부모의 상태를 바꿀 순 없을까? onBut(); };
함수 내에서 일어난 일이 함수 외부에도 영향을 끼치는 경우 이를
Side effect
가 있다고 한다.
리엑트에서 Side effect 는 무엇이 있을까?
React의 함수 컴포넌트는, props가 입력으로, JSX Element가 출력으로 나갑니다.
여기에는 그 어떤 Side Effect도 없으며, 순수 함수로 작동합니다.
React 함수 컴포넌트 예시
function SingleTweet({ writer, body, createdAt }) {
return <div>
<div>{writer}</div>
<div>{createdAt}</div>
<div>{body}</div>
</div>
}
오직 함수의 입력 값만이 함수의 결과에 영향을 주는 함수를 말한다.
함수 입력 값이 아닌 다른 값이 함수의 결과에 영향을 준다면 이는 순수 함수가 아님
그렇기 때문에 예측 가능한 함수라고도 함.
React 함수 컴포넌트는 순수 함수라고 했다.
근데 함수 컴포넌트
에 네트워크 요청이나 타이머와 같은 Side effect
가 발생하면 순수 함수가 아니게 되므로
React 에서 Side effect
를 다루기 위해 Effect Hook
이란걸 사용한다.
useEffect 는 컴포넌트 내에서
Side effect
를 실행 할 수 있게 하는Hook
이다.
컴포넌트가 렌더링 될때마다 useEffect
전달인자로 들어온 함수가 실행된다.!
전달인자로는 함수와 [dependency array] 인 종속성 배열을 가진다.
종속성 배열은 선택사항이다.
[dependency array] 종속성 배열은 조건을 담고 있다.
이 조건은 불리언 값이 아닌 어떤 값의 변경이 일어날때를 의미한다.
따라서 이 배열안에는 어떠한 값이 들어가는 것이다!
상태는 변경될 수 있으니 상태의 변수가 들어가는게 보통이다.
여러 값도 넣을 수 있다. [상태1, 상태2] 이렇게
그럼 상태1, 상태2 가 변경될때마다 컴포넌트가 렌더링이 일어나고 해당 Side effect
도 실행되는 것이다.
상태3 이 변경되는 경우에는 컴포넌트만 렌더링 되고 Side effect
는 실행안된다.
빈 배열을 넣는다면 Side effect
는 단 한번만 실행이 된다.
배열 자체를 넣지 않는다면 (인자가 함수만 있다면) 계속 컴포넌트가 렌더링 일어 날 때마다 Side effect
는 실행된다.
사진 출처 : 코드스테이츠