안녕하세요.
Hynn 입니다.
이번 포스팅에서는 상태 끌어올리기 (Lifting State up) 에 대해서 알아보도록 하겠습니다.
유사한 방법으로는 Sharing State Between Components, 컴포넌트 간 상태 공유 라는 방법도 존재합니다. 이에 대해서는 가볍게 개념과 기본 동작형태만 알아보도록 하겠습니다.
이에 대해서 각각 알아보도록 하겠습니다.
============
============
1.상태 끌어올리기와 컴포넌트 간 상태 공유에 대해서 알아보기.
먼저 아래의 그림을 통해, 각각의 Component 의 구조가 어떻게 이루어지는지를 살펴보겠습니다.
이 개념도를 이전 포스팅에서도 잠시 다룬 적이 있습니다.
React 에서는 기본적으로 데이터 흐름(Data Flow) 는 단방향으로 흐름에 대해서 설명드린 바 있습니다.
즉 데이터는, 자식컴포넌트에서 출발하여 부모컴포넌트로, 혹은 부모컴포넌트에서 출발하여 자식컴포넌트로 흐르는 방향으로만 진행됩니다. 이 각각의 데이터 흐름은 아래의 명칭으로 부릅니다.
- Top-down data-flow ( 부모에서 자식 )
- upward data-flow ( 자식에서 부모 )
즉, 기초적인 State 끌어올리기는, 하나의 Component 내에서 부모 자식간의 데이터 이동흐름을 뜻합니다.
반면, 위에서 언급한 Sharing State Between Components , 컴포넌트 간 상태 공유는 이러한 제약사항이 존재하지 않습니다.
다만 이러한 사용을 위해서는 나중에 다루게 될 Redux 와 같은 Library 를 사용해야 합니다.
위 개념을 보다 자세히 알고 싶으신 분들은 "Sharing State Between Components" 을 방문하시어 React Official 문서의 세부정보를 참조할 수 있습니다.
2. Lifting State Up 기본 이용해보기.
이를 이용하기 위해서는 부모/자식 관계를 갖는 컴포넌트를 작성해보도록 하겠습니다.
먼저 예시 코드를 살펴보도록 하겠습니다.
const { useState } = React
const Panel = ({title, children}) => {
const [isActive, setIsActive] = useState(false)
return (
<section className="panel">
<h3>{title}</h3>
{isActive ? (<p>{children}</p>) : (<button onClick={()=> setIsActive(true)}>Show</button>)}
</section>
)
}
const Sales = () => {
return (
<>
<h2> Hynn Tistory Blog</h2>
<Panel title="About">
이 이용약관은 어디어디~저기저기~요리보고~저리봐도~둘리~둘리
</Panel>
<Panel title="TermsOfSales">
빙하타고~내려와~만났지만~둘리~둘리~
</Panel>
</>
)
}
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<Sales />)
위의 Component 는 State 끌어올리기가 적용 된 것일까요?
먼저 State를 살펴보면 이는 간단합니다.
현재 State를 관리하는것은 Panel 입니다.
하지만 Panel 은 Sales 의 자식 Component 입니다. 즉, 자식 Component 내에서만 처리되는 State 입니다.
이를 보다 시각적으로 확인하기 위해서, "React Developer Tools" 를 적용해보면 아래와 같이 표시되는것을 살펴볼 수 있습니다.
현재의 코드를 살펴보면, 상위 컴포넌트인 Sales 에는 State 가 존재하지 않지만 Panel 에는 State 가 존재합니다.
즉 이 코드는 Lifting State up 처리가 되지 않고, 자식 컴포넌트에서만 처리가 되는 개념입니다.
이는 코드의 효율상 좋지 않기도 합니다. 부모 컴포넌트에 이 State 가 전달이 되면, 다른 Component 에서도 이 값을 전달받아 이를 사용할 테니까 말입니다.
이에 맞추어 코드를 수정해보겠습니다.
const { useState } = React
const Panel = ({ title, children, isActive, setIsActive }) => {
return (
<section className="panel">
<h3>{title}</h3>
{isActive ? (<p>{children}</p>) : (<button onClick={() => setIsActive(true)}>Show</button>)}
</section>
)}
const Sales = () => {
const [isAboutActive, setIsAboutActive] = useState(false)
const [isTermsActive, setIsTermsActive] = useState(false)
return (
<>
<h2> Hynn Tistory Blog</h2>
<Panel title="About" isActive={isAboutActive} setIsActive={setIsAboutActive}>
이 이용약관은 어디어디~저기저기~요리보고~저리봐도~둘리~둘리
</Panel>
<Panel title="TermsOfSales" isActive={isTermsActive} setIsActive={setIsTermsActive}>
빙하타고~내려와~만났지만~둘리~둘리~
</Panel>
</>
)}
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<Sales />)
위의 코드에서는 이전의 Key 의 대한 예제도 일부가 포함되어 있습니다.
먼저 코드를 살펴보면 State 관리가 Panel 에서 Sales 로 이동된 것을 볼 수 있습니다. Panel 은 구조분해형태로 Title, Children, isActive, onToggle 4개의 State 를 Props 를 이용해 전달을 받았습니다.
즉 자식 Component 인 Panel 은 부모 Sales Components 로부터 전달받은 것을 바탕으로 panel 은 삼항 연산자를 사용하여, 그리도록 설계되어 있습니다.
또한 여기서는 title, isActive, setIsActive 에서는 이름을 개별적으로 분리하여, 각각 개별적으로 동작되도록 작성이 되어 있습니다.
이는 이전 포스팅에서 언급한 Key 에서의 고유한 명칭을 중복되지 않도록 설정한 것을 의미하며, 이를 중복하여 작성했을때, 코드의 결과물에서 어떤 버튼을 누르더라도 두개가 같이 동작되는 모습을 볼 수 있습니다. 이는 의도한 동작이 아닐 겁니다.
위의 코드를 React Developer Tool 을 사용하여 살펴보면 아래와 같이 표시되는 것을 살펴볼 수 있습니다.
이 코드 작성이 Lifting State up 을 적용한 예제 코드입니다.
Developer Tool 에서도 부모 컴포넌트인 Sales 에는 Hooks 라는 이름으로 각각의 State 가 나타나는 것을 볼 수 있습니다.
이전 포스팅에서도 State 끌어올리기 요소가 준비되어 있습니다.
이러한 점들을 고려하여 React 를 작성한다면 재사용에서도 아주 유용한 컴포넌트가 될 겁니다.
다음 포스팅에서는 React 에서 사용하는 합성, 상속에 대해서 알아보고, 기본 개념을 마무리하는 포스팅을 작성할 예정입니다.
감사합니다.
'개발공부일지 > React' 카테고리의 다른 글
React - Module-Bundler(Feat. WebPack) 알아보기 (0) | 2023.03.14 |
---|---|
React - 합성/상속 알아보기 (0) | 2023.03.07 |
React - Form 사용하기 (0) | 2023.03.06 |
React - List & Key 사용하기 (0) | 2023.03.06 |
React - 조건부 랜더링 (0) | 2023.02.28 |
댓글