React.js에서 "상태 끌어올리기"란 여러 컴포넌트에서 공유하는 상태를 부모 컴포넌트로 옮겨서 관리하는 것을 말한다.
이런 의미에서 상태 끌어올리기는 State를 통해 상태를 관리하는 기능이라고 볼 수 있다.
React.js의 indeed 단방향 데이터 흐름
React.js는 부모 컴포넌트에서 자식 컴포넌트로 props를 통해 데이터를 전달하고, 자식 컴포넌트에서는 이를 받아서 화면에 렌더링하는 방식으로 작동한다. 자식 컴포넌트에서 상태를 변경해도, 이 변경된 상태는 항상 상위 컴포넌트로 전달되어 최종적으로 애플리케이션의 상태가 업데이트되게 된다.
** 사설
이 때, 본인은 자식 컴포넌트에서 상태를 변경해도 부모 컴포넌트로 전달된다는 개념이 너무~~~~너무 이해가 되지 않았다.
" 자식 컴포넌트로 상태를 props로 내려보내서, 자식 컴포넌트에서 상태를 제어한다면 부모 컴포넌트는 모르는게 아닌가? "
또한 어차피 렌더링 되는 건, 부모 컴포넌트에서 조립된 자식 컴포넌트이지 부모 컴포넌트 자체로 통합되는게 아니지 않을까?라는 고민이 되었다.
이에 관한 이해는 다음 주제의 예시 코드에서 살펴보면 된다.
이러한 단방향 데이터 흐름은 다음과 같은 장점을 갖는다.
1. 데이터 흐름이 단순하여 에러가 발생할 경우 추적(디버깅)에 용이하다.
2. 부모 컴포넌트에서 통합하여 관리되기 때문에 유지보수에 용이하다.
3. 상태 변경시 하나의 컴포넌트에서 관리되기 때문에 일관성과 안정성이 보장된다.
상태 끌어올리기 예시
상태 끌어올리기는 "개념"이지 문법이 아니다. 더불어 상태 끌어올리기는 React.js의 단방향적 데이터 흐름에 부합한 개념이다.
import React, { useState } from "react";
// 자식 컴포넌트
function ChildComponent(props) {
const [count, setCount] = useState(0);
console.log(props);
function handleButtonClick() {
setCount(count + 1); // 버튼 클릭 시 count 상태를 1 증가시킴
props.onButtonClick(count + 1); // 상태 변화를 부모 컴포넌트로 전달함
}
return (
<div>
<p>Count: {count}</p>
<button onClick={handleButtonClick}>Click me!</button>
</div>
);
}
// 부모 컴포넌트
function ParentComponent() {
const [childCount, setChildCount] = useState(0);
function handleChildButtonClick(count) {
setChildCount(count); // 자식 컴포넌트에서 전달받은 count 상태를 부모 컴포넌트에서 관리함
}
return (
<div>
<p>Child count: {childCount}</p>
<ChildComponent onButtonClick={handleChildButtonClick} />
</div>
);
}
export default ParentComponent;
위의 코드를 뜯어보면 부모 컴포넌트에서 이미 어떤 상태를 관리하는 useState()가 활용되고 있음을 알 수 있다.
그리고 단순히 props로 어떤 객체나 값을 내려보내는 것이 아닌 "상태 변경 함수" 자체가 포함된 함수를 내려보내고 있음을 알 수 있따.
// 부모 컴포넌트
function ParentComponent() {
const [childCount, setChildCount] = useState(0);
function handleChildButtonClick(count) {
setChildCount(count); // 자식 컴포넌트에서 전달받은 count 상태 담아낼 setChildCount() 함수
}
return (
<div>
<p>Child count: {childCount}</p>
{/* 해당 함수를 props로 내려주고 있음 */
<ChildComponent onButtonClick={handleChildButtonClick} />
</div>
);
}
이제 이 함수는 자식 컴포넌트에서 prop로 활용될 수 있고, 자식 컴포넌트에서 변경된 상태값을 가져올 수 있다.
// 자식 컴포넌트
function ChildComponent(props) {
const [count, setCount] = useState(0);
console.log(props);
// {onButtonClick: ƒ handleChildButtonClick()}
// ===> onButtonClick: ƒ handleChildButtonClick() {}
// ===> <constructor>: "Function"
function handleButtonClick() {
setCount(count + 1); // 버튼 클릭 시 count 상태를 1 증가시킴
props.onButtonClick(count + 1); // 상태 변화를 부모 컴포넌트에서 받아온 setChildCount 함수에 인자로 전달한다.
console.log(props.onButtonClick(count + 1));
// onButtonClick: ƒ handleChildButtonClick() {} 여기에 인자로 (count+1)을 전달!
}
return (
<div>
<p>Count: {count}</p>
<button onClick={handleButtonClick}>Click me!</button>
</div>
);
}
자식 컴포넌트에서 setChildCount() 상태변경 함수가 변경되었음으로 부모 컴포넌트는 useState()의 문법에 따라 childCount 변수를 새로운 상태로 재할당할 것이고, 상태가 업데이트 되었으니 컴포넌트 자체를 리렌더링 시킬 것이다.
이렇게, 상태 끌어올리기 개념을 활용해 부모 컴포넌트에서도 자식 컴포넌트의 상태를 반영한 렌더링이 이뤄질 수 있는 것이다.
정리
즉, 상태 끌어올리기의 개념은 자식 컴포넌트의 상태를 관리할 새로운 함수와 useState()를 정의하고 이를 자식 컴포넌트에 prop로 내려주는 단방향적 흐름에 일치한다.
이를 활용하여 childCount 변수는 다른 컴포넌트에서 props로 전달받아 활용할 수 있고, 이를 통해 자식 컴포넌트에서 상태가 변경되었을지라도 부모 컴포넌트를 통해 관리되는 일관성과 유지보수성을 확보할 수 있게 된다.
'프레임워크&라이브러리 > React.js' 카테고리의 다른 글
(SPA) React-Router-Dom (0) | 2023.03.06 |
---|---|
UseRef() (0) | 2023.02.22 |
Styled Component (0) | 2023.02.20 |
useState(), useEffect() (0) | 2023.02.13 |
States & Props (feat. eventHandler) (0) | 2023.02.06 |