[Hook] - State 끌어올리기

Donggu(oo)·2022년 11월 30일
0

React

목록 보기
16/30
post-thumbnail

1. State 끌어올리기(Lifting State Up)


  • 동일한 데이터를 여러 컴포넌트에서 사용하고, 변경됐을 때 바로 반영되어야 한다면 각 컴포넌트가 state를 가지고 있는 것이 아니라 공통된 상위 컴포넌트에서 state를 처리하고, 하위 컴포넌트에서는 상위로 전달하는 방법을 사용해야 한다. React에서는 이 방법을 State 끌어올리기라고 한다.

  • state 끌어올리기상위 컴포넌트의 "상태를 변경하는 함수" 그 자체를 하위 컴포넌트로 전달하고, 이 함수를 하위 컴포넌트가 실행하는 것을 말한다.

  • 상태 변경 함수(콜백 함수)를 자식에게 props로 전달하고, 자식에서 해당 함수를 호출하면 부모의 state가 변동되는 원리이다.

  • 즉, state의 변화는 컴포넌트 내부에서만 이루어지지만, 이러한 변화를 일으키는 호출을 외부(자식 컴포넌트)에서 함으로서 마치 외부에서 내부 state를 변화시키는 것 같은 효과를 가진다.

1) 하위 컴포넌트의 이벤트로 상위 컴포넌트의 상태 변경하기

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

  • '상태 변경 함수'는 버튼이 클릭할 때 실행되야 하므로, 해당 부분에 콜백 함수를 실행한다.

// 부모(상위) 컴포넌트
function ParentComponent() {
    const [value, setValue] = useState("부모 컴포넌트의 state 값");

    const handleChangeValue = () => {
        setValue("변경된 값");
    };

    return (
        <div>
            <div>{`끌어올리기 결과값: ${value}`}</div>
            <ChildComponent handleButtonClick={handleChangeValue} />
        </div>
    );
}

// 자식(하위) 컴포넌트
function ChildComponent({ handleButtonClick }) {
    const handleClick = () => {
        handleButtonClick();
    };

    return <button onClick={handleClick}>값 변경</button>;
}
  • 필요 시 설정할 값을 콜백 함수의 인자로 넘길 수도 있다.
// 부모(상위) 컴포넌트
function ParentComponent() {
    const [value, setValue] = useState("부모 컴포넌트의 state 값");

    const handleChangeValue = (newValue) => {
        setValue(newValue);
    };

    return (
        <div>
            <div>{`끌어올리기 결과값: ${value}`}</div>
            <ChildComponent handleButtonClick={handleChangeValue} />
        </div>
    );
}

// 자식(하위) 컴포넌트
function ChildComponent({ handleButtonClick }) {
    const handleClick = () => {
        handleButtonClick("변경된 값");
    };

    return <button onClick={handleClick}>값 변경</button>;
}
  • 버튼 클릭 시 자식 컴포넌트의 값이 반영되는 것을 확인할 수 있다.

2) 여러 개의 하위 컴포넌트의 값을 동시에 변경하기(동기화)

  • 자식 컴포넌트가 각각의 state를 가지고 있는 것이 아닌 부모 컴포넌트의 state값을 받고 있다.
// 부모(상위) 컴포넌트
export default function Parent() {
    
    const [count, setCount] = useState(0);

    function onClickCounter() {
        setCount(count + 1);
    }

    return (
        <>
            <FirstChild count={count} onClickCounter={onClickCounter} />
            <div>===========</div>
            <SecondChild count={count} onClickCounter={onClickCounter} />
        </>
    );
}

// 자식(하위) 컴포넌트1
export default function FirstChild({ count, onClickCounter }) {
    return (
        <div>
            <div>자식1 카운트: {count}</div>
            <button onClick={onClickCounter}>카운트올리기</button>
        </div>
    );
}
// 자식(하위) 컴포넌트2
export default function SecondChild({ count, onClickCounter }) {
    return (
        <div>
            <div>자식2 카운트: {count}</div>
            <button onClick={onClickCounter}>카운트올리기</button>
        </div>
    );
}
  • 어느 쪽의 버튼을 클릭해도 동시에 카운트가 올라가는 것을 확인할 수 있다.

2. 예제


  • 자식 컴포넌트에 있는 버튼을 클릭해도 게시글 추가가 정상적으로 동작하는 것을 확인할 수 있다.

0개의 댓글