[06.21] 상태 관리

0
post-thumbnail

목차

  • 전역 상태 관리
  • Props Drilling
  • 회고

📌 전역 상태 관리

상태관리

상태란?

: UI에 동적으로 표현될 데이터

UI에서 상태 찾기

  • 상태에 따라 어떤 화면이 영향을 받는지 확인
  • 각 컴포넌트들이 서로 어떤 상태를 공유하고 주고 받는지 확인

[예시 : 장바구니 화면에서 상태 찾기]

  • 아이템 페이지에서 "장바구니 담기" 버튼을 눌러 해당 물품을 장바구니에 추가할 수 있음
  • 상단에 [일반구매][정기배송] 중 현재 선택되는 탭
  • 상품 선택 여부에 따른 주문 금액이나 배송비가 달라짐
  • 상품 수량을 추가하거나 삭제하기

Side Effect

: 함수의 입력 외에도 함수의 결과에 영향을 미치는 요인

➡️ 대표적으로 네트워크 요청, API 호출이 있음

[예시]
UI상태 찾기 연습에서 보았던 장바구니의 아이템(컴포넌트)들을 API로 받아오는데, 데이터 전송여부에 따라 로딩이 길어질 수 있음

로컬과 전역

  • 로컬 : 특정 컴포넌트 안에서만 관리 되는 상태
    -> 다른 컴포넌트들과 데이터를 공유받지 않고 서로 영향을 미치지도 끼치지도 않는 상태
  • 전역 : 프로덕트 전체 혹은 여러 컴포넌트에서 관리 되는 상태
    -> 다른 컴포넌트와 상태를 공유하고 서로 영향을 미치는 상태

각 컴포넌트가 개별로 상태를 갖고 있으면 안되나?

➡️ 서로 다른 컴포넌트가 사용하는 상태의 종류가 다르면, 서로 다른 출처(source)가 있어도 상관 x

하지만, 서로 다른 컴포넌트가 동일한 상태를 다룬다면, 서로 다른 출처로부터 가져오는 것은 피해야 함

전역 상태 관리 Case Study

  • 웹 페이지 혹은 앱을 사용할때 라이트모드와 다크모드가 있다.
    이러한 설정은 전역으로 관리하여 모든 페이지, 컴포넌트에 적용되게 할 수 있다.
  • 웹 페이지 혹은 앱을 사용시 어떤 언어로도 접근할 수 있게 전역 상태로 관리하기도 한다.

📌 Props drilling

: 상위컴포넌트의 state를 props를 통해 전달하고자 하는 컴포넌트를 전달하기 위해 컴포넌트를 거치면서 React Component 트리의 한 부분에서 다른 부분으로 데이터를 전달하는 과정

[예시(링크)]

import React, { useState } from 'react';
import styled from 'styled-components';

const Container = styled.div`
border: 5px solid green;
padding: 10px;
margin: 10px;
position: relative;
`;

const Quantity = styled.div`
text-align: center;
color: red;
border: 5px solid red;
padding: 3px;
font-size: 1.2rem;
`;

const Button = styled.button`
margin-right: 5px;
`;

const Text = styled.div`
color: ${(props) => (props.color ? props.color : 'black')};
font-size: ${(props) => (props.size ? props.size : '1rem')};
font-weight: ${(props) => (props.weight ? '700' : 'inherit')};
`;

export default function App() {
const [number, setNumber] = useState(1);

const plusNum = () => {
  setNumber(number + 1);
};

const minusNum = () => {
  setNumber(number - 1);
};
console.log('Parents');
return (
  <Container>
    <Text weight size="1.5rem">
      [Parents Component]
    </Text>
    <Text>
      Child4 컴포넌트에 있는 버튼을 통해
      <br /> state를 변경하려고 합니다.. 🤮
    </Text>
    <Text weight color="tomato">
      Props Driling이 발생!!
    </Text>
    <Quantity>{`수량 : ${number}`}</Quantity>
    <Child1 plusNum={plusNum} minusNum={minusNum} />
  </Container>
);
}

function Child1(
{
  /* props로 전달받은 plusNum, minusNum를 가져오세요 */
  plusNum,minusNum
}
) {
console.log('Child1');
return (
  <Container>
    <Text>[Child 1 Component]</Text>
    {/* plusNum, minusNum 함수를 props로 전달해주세요! */}
    <Child2 plusNum={plusNum} minusNum={minusNum}/>
  </Container>
);
}

function Child2(
{
  /* props로 전달받은 plusNum, minusNum를 가져오세요 */
  plusNum,minusNum
}
) {
console.log('Child2');
return (
  <Container>
    <Text>[Child 2 Component]</Text>
    {/* plusNum, minusNum 함수를 props로 전달해주세요! */}
    <Child3 plusNum={plusNum} minusNum={minusNum}/>
  </Container>
);
}

function Child3(
{
  /* props로 전달받은 plusNum, minusNum를 가져오세요 */
  plusNum,minusNum
}
) {
console.log('Child3');
return (
  <Container>
    <Text>[Child 3 Component]</Text>
    {/* plusNum, minusNum 함수를 props로 전달해주세요! */}
    <Child4 plusNum={plusNum} minusNum={minusNum}/>
  </Container>
);
}

function Child4({ plusNum, minusNum }) {
console.log('Child4');
return (
  <Container>
    <Text>[Child 4 Component]</Text>
    <Button onClick={plusNum}>👍</Button>
    <Button onClick={minusNum}>👎</Button>
  </Container>
);
}

< Props Drilling 단점 >

❗️props의 전달횟수가 5회 이내로 많지 않다면 큰문제가 되지 않지만 더 많아진다면?

  • 코드의 가독성이 매우 나빠짐
  • 코드의 유지보수가 힘듬
  • state 변경시 props 전달 과정에서 불필요한 컴포넌트까지 리렌더링이 되면서 성능이 떨어짐

⚒️ 해결

  • 컴포넌트와 관련 있는 state는 가까이 유지
  • 상태관리 라이브러리 사용 (Redux, Context api, Mobx등)

0개의 댓글