본문 바로가기
FE/React

state Lifting

by ideal_string 2022. 9. 26.

state를 활용하다보면 같은 값을 공유하고 싶은 컴포넌트가 생긴다. 이 컴포넌트에서 입력한 값이 다른 컴포넌트에서도 반영되길 바라는 것.  props를 떠올릴 텐데 좋은 접근이다. 다만 props는 형제 요소에겐 줄 수 없다. 이때 필요한게 state lifting이다. 버튼을 누를 때 1씩 늘어나는 컴포넌트와, 10씩 늘어나는 컴포넌트로 예시를 들어본다.

먼저 메인페이지를 만들고 컴포넌트를 만들었다. 그리고 각각 함수를 설정했다.

index.jsx

import Count_first from "./Count_first";
import Count_second from "./Count_second";

export default function Main() {
  return (
    <>
      <Count_first />
      <Count_second />
    </>
  );
}

Count_first.jsx

import { useState } from "react";

export default function Count_first() {
  const [upOne, setUpOne] = useState(0);

  const onClickInput = () => {
    setUpOne(Math.round(upOne + 1));
  };

  return (
    <>
      <div>
        <button onClick={onClickInput}>Count_first</button>
      </div>
      <div>{upOne}</div>
    </>
  );
}

Count_cecond.jsx

import { useState } from "react";

export default function Count_second() {
  const [upTwo, setUpTwo] = useState(0);

  const onClickInput = () => {
    setUpTwo(Math.round(upTwo + 10));
  };

  return (
    <>
      <div>
        <button onClick={onClickInput}>Count_second</button>
      </div>
      <div>{upTwo}</div>
    </>
  );
}

 

 

이렇게 사용하면 버튼 하나에 두 컴포넌트에 두 가지 결과가 나타난다. 이제 첫번째 컴포넌트의 버튼을 누르든, 두번째 컴포넌트 버튼을 누르든 양쪽에 모두 반응하도록 바꿔볼 예정이다. 사실 state lifting은 아주 간단하다. 형제끼리 영항을 주고 받을 수 없으니 두 컴포넌트의 공통 요소인 부모 컨포넌트로 state를 옮기는 거다.

 

index.jsx

import { useState } from "react";
import Count_first from "./Count_first";
import Count_second from "./Count_second";

export default function Main() {
  const [count, setCount] = useState(0);

  return (
    <>
      <Count_first count={count} setCount={setCount} />
      <Count_second count={count} setCount={setCount} />
    </>
  );
}

Count_first.jsx

export default function Count_first({ count, setCount }) {
  const onClickInput = () => {
    setCount(Math.round(count + 1));
  };

  return (
    <>
      <div>
        <button onClick={onClickInput}>Count_first</button>
      </div>
      <div>{count}</div>
    </>
  );
}

Count_cecond.jsx

export default function Count_second({ count, setCount }) {
  const onClickInput = () => {
    setCount(Math.round(count + 10));
  };

  return (
    <>
      <div>
        <button onClick={onClickInput}>Count_second</button>
      </div>
      <div>{count}</div>
    </>
  );
}

마무리

리액트는 자바스크립트와 같이 스크립트 언어처럼 위에서부터 순차로 읽는 것을 알고, props를 내려보내는 drilling을 이해한다면, 당연하 두 컴포넌트에 존재해야하는 상태관리가 필요할 땐 부모 컨포넌트에 넣을 수 밖에 없다. 그럼에도 리액트 문서에서 state lifting을 설명하고 있다는 건, 이유가 있다고 생각할 뿐이다. 추축컨데 큰 프로젝트를 하다보면 리팩토링할 때 state를 올려야할 때가 생기기 때문에, 이를 인지하고 있길 바라는 마음으로 서술해둔 건 아닐까 싶다. 나도 혹시몰라 정리해둔다. 잊지 말길...!

※ 잘못된 내용이 있을 경우 댓글로 알려주세요. 배우고 익히고 수정하겠습니다:)

'FE > React' 카테고리의 다른 글

useEffect  (1) 2022.09.30
useRef  (0) 2022.09.29
Container-Presenter  (0) 2022.09.21
static routing & dynamic routing  (0) 2022.09.19
React state, prev & props, children  (0) 2022.09.17