[TIL] 20210510_state 끌어올리기

BANSEOK SUH·2021년 5월 10일
0

TIL

목록 보기
11/22
post-thumbnail

state란?

컴포넌트 내에서 변할 수 있는 값을 말합니다.

컴포넌트 내에서 입력, 수정, 삭제되는 데이터라고 이해하면 될 것 같습니다.

상태 변화

컴포넌트 내의 state에 어떠한 변화가 있다면(수정, 삭제가 되었다면), 'state의 상태가 변화됐다'라고 표현합니다. 그리고 그러한 변화를 관리하는 것을 '상태관리'라고 합니다.

한 컴포넌트 안에서 state에 변화를 주는 것은 어렵지 않습니다.

하지만 다음과 같이 하위 컴포넌트에서 부모 컴포넌트의 state에 변화를 주려면 어떻게 해야 할까요?

'데이터는 단방향(위에서 아래로)으로 흐른다'라는 리액트의 원칙 앞에서, 어떻게 해야 자식 컴포넌트가 부모 컴포넌트의 상태를 변화시킬 수 있을까요.

그 답은 다음과 같습니다.

  1. 상위 컴포넌트의 '상태를 변경하는 함수' 그 자체를 하위 컴포넌트로 전달하고
  2. 이 함수를 하위 컴포넌트가 실행한다.

천천히 살펴보겠습니다.


하위 컴포넌트에 함수 전달

먼저 상위 컴포넌트입니다.
기존의 상태상태를 변경하려는 함수가 정의되어 있고, ChildComponent라는 하위 컴포넌트를 갖습니다.

class ParentComponent extends React.Component {
  constructor(props) {
    super(props);
    // 상태
    this.state = {
      value: "========== 기존값 =========="
    };
    ...
  }

  // 상태를 변경하는 함수
  handleChangeValue() {
    ...
  }

  // 렌더링
  render() {
    return (
      <div>
        <div>값은 {this.state.value} 입니다</div>
        <ChildComponent /> // 하위 컴포넌트
      </div>
    );
  }
}

하위 컴포넌트인 ChildComponent에서 상위 컴포넌트의 상태를 변경하려고 합니다.
그렇다면 어떻게 해야 한다고 했죠?

  1. 상위 컴포넌트의 '상태를 변경하는 함수' 그 자체를 하위 컴포넌트로 전달하고
  2. 이 함수를 하위 컴포넌트가 실행한다.

위 과정 중 1번을 코드로 옮겨보겠습니다. 상위 컴포넌트의 렌더링 부분입니다.

// 렌더링
  render() {
    return (
      <div>
        <div>값은 {this.state.value} 입니다</div>
        <ChildComponent clickHandler={this.handleChangeValue}/> // 상위 컴포넌트의 함수를 props로 전달했습니다.
      </div>
    );
  }

clickHandler라는 이름으로 하위 컴포넌트에 상태를 변경하는 함수를 전달했습니다.
그렇다면 1번 과정이 끝난 겁니다!


state 끌어올리기

하위 컴포넌트에서 함수 실행

다음은 상위 컴포넌트로부터 함수를 전달받는 하위 컴포넌트입니다.

// 하위 컴포넌트
// 컴포넌트의 첫번째 인자는 props 객체인데, 구조분해할당을 통해 clickHandler에 직접 접근했습니다.
function ChildComponent({ clickHandler }) {
  
  // JSX로 버튼을 리턴해줍니다. 클릭 시에 clickHandler 함수가 실행됩니다.
  return <button onClick={() => clickHandler('xxxxxxxxxx 바뀐값 xxxxxxxxxx')}>값 변경</button>;
}

하위 컴포넌트에서는 버튼을 리턴하는데, 버튼 클릭 시에 onClick 이벤트로 인해 상위 컴포넌트로부터 전달받은 clickHandler 함수를 실행시킵니다. 버튼이 클릭될 때에 실행이 되어야 하므로 **콜백 함수의 형태**로 실행을 시키네요. **콜백 함수의 인자로는 state에 반영할 값**이 들어갑니다.

여기까지 2번의 과정이 끝났습니다!

다시 상위 컴포넌트에서 정의한 함수로 올라가보겠습니다.

상위 컴포넌트에서 상태 변화

하위 컴포넌트로 전달한 상태를 변경할 함수를 살펴보겠습니다.
setState() 메서드를 이용해 상태를 변화시키는데요, 먼저 객체를 이용한 경우를 살펴보겠습니다.

객체를 이용한 상태 변화

// 상위 컴포넌트
...

// 상태를 변경하는 함수
handleChangeValue(data) {
  
  this.setState({
    value: data
  });
  
}

...

실행 시 하위 컴포넌트에서 끌어올려진 변수(data)를 사용해 상태를 변화시키는데요,
setState() 메서드에 객체를 인자로 하여 상태를 변화시키고 있습니다.

기존의 상태를 참조하지 않아도 되는 경우에 객체를 이용해 상태를 변화시킵니다.

콜백 함수를 이용한 상태 변화

다음은 콜백함수를 이용한 경우입니다.

handleChangeValue(data) {
  
  this.setState((prevState) => {
    return {
      ...prevState,
      value: data
    };
  });
  
}

콜백함수를 이용하게 되면, 콜백함수의 첫 번째 인자로 기존의 상태(prevState)가 들어오게 됩니다.
기존의 상태를 spread operation을 통해서 한 번 펼쳐주고, 그 다음으로 추가하고자 하는 데이터를 추가합니다. 구조분해할당을 유의미하게 사용했습니다.

이 경우는 기존의 상태를 참조해야 하는 경우에 주로 쓰입니다.


하지만 리액트에서는 후자의 방법(콜백함수를 통한 상태변화)을 지향한다고 합니다.

profile
HelloBanny

0개의 댓글