CodeStates/React

Section2 / Unit9 : state 끌어올리기

yeeendy 2023. 5. 30. 20:14

state 끌어올리기 (Lifting State Up)

리액트는 단방향 데이터 흐름이라는 원칙에 따라

  • 하위 컴포넌트는 상위 컴포넌트로부터 전달받은 데이터의 형태 혹은 타입이 무엇인지만 알 수 있다
  • 데이터가 state로부터 왔는 지, 하드코딩으로 입력한 내용인지는 알지 못한다.
  • 그러므로 하위 컴포넌트에서의 어떤 이벤트로 인해 상위 컴포넌트의 상태가 바뀌는 것은 마치 "역방향 데이터 흐름"처럼 보인다

해결 방안

상위 컴포넌트의 '상태를 변경하는 함수' 그 자체를 하위 컴포넌트로 전달하고, 이 함수를 하위 컴포넌트가 실행한다
-> 상태 끌어올리기
-> 콜백 함수 사용법과 비슷

예제

import React, { useState } from "react";

export default function ParentComponent() {
  const [value, setValue] = useState("날 바꿔줘!");

  const handleChangeValue = () => {
    setValue("보여줄게 완전히 달라진 값");
  };

  return (
    <div>
      <div>값은 {value} 입니다</div>
      <ChildComponent />
    </div>
  );
}

function ChildComponent() {
  const handleClick = () => {
    // 이 버튼을 눌러서 부모의 상태를 바꿀 순 없을까?
  };

  return <button onClick={handleClick}>값 변경</button>;
}

상태를 변경하는 함수는 handleChangeValue이고, 전달은 props를 이용하자

이름음 임의로 handleBtnClick라 하겠음

-> (하위 컴포넌트가 버튼 클릭 이벤트에 따라 상태를 변경하려고 하므로)

<ChildComponent>는 마치 고차 함수가 인자로 받은 함수를 실행하듯, props로 전달받은 함수를 컴포넌트 내에서 실행할 수 있게 한다

"상태 변경 함수"는 버튼이 클릭할 때 실행되기를 원하므로, 해당 부분에 콜백 함수를 실행

import React, { useState } from "react";

export default function ParentComponent() {
  const [value, setValue] = useState("날 바꿔줘!");

  const handleChangeValue = () => {
    setValue("보여줄게 완전히 달라진 값");
  };

  return (
    <div>
      <div>값은 {value} 입니다</div>
      <ChildComponent handleBtnClick = {handleChangeValue}/> //하위 컴포넌트에 넘겨주기
    </div>
  );
}

function ChildComponent({handleBtnClick}) { //props로 전달
  const handleClick = () => {
    // 이 버튼을 눌러서 부모의 상태를 바꿀 순 없을까?
    handleBtnClick() //실행
  };

  return <button onClick={handleClick}>값 변경</button>;
}