React/React 문법

[React]setState Callback 함수 사용

DevStory 2021. 10. 18.

이번 포스팅에서는 React에서 setState의 Callback 함수를 사용하는 경우를 소개합니다.

 


setState의 Callback 함수를 사용하는 경우

react에서 setState의 Callback 함수를 사용하는 경우는 state를 변경 후 변경된 state를 사용하는 경우입니다.

 

우선, Callback 함수를 사용하지 않은 경우 어떠한 문제가 발생하는지 알아봅시다.

 

다음은 [* 2] 버튼을 클릭하면 this.state.num의 값을 2배로 변경 후 콘솔에 this.state.num의 값을 출력하는 함수입니다.

twiceButtonClick = () => {
    this.setState({ num: this.state.num * 2 });
    console.log("state : " + this.state.num);
  };

실행 결과

[* 2] 버튼을 클릭 전 결과입니다.

[* 2] 버튼 클릭 전

[* 2] 버튼을 클릭 후 결과입니다.

[* 2] 버튼 클릭 후

setState 함수가 실행되어 this.state.num의 값이 2로 변경되었는데, 콘솔에는 변경되기 전 값이 출력되었습니다.

 

이러한 이유는 setState가 비동기 함수라서 그렇습니다.

 

setState 함수는 이벤트 핸들러 함수에서 바로 값을 갱신(변경)하는 것이 아니라 이벤트 핸들러 함수가 종료 후 react에 의해 state 값이 갱신됩니다.

 

setState 함수로 state의 값을 변경 후 갱신된 값을 콘솔에 출력하기 위해서는 setState의 Callback 함수를 사용해야 합니다.

반응형

Class 컴포넌트의 setState Callback

다음 코드는 setState 함수의 정의인데, 2개의 인자가 존재합니다.

setState<K extends keyof S>(
  state: ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null),
  callback?: () => void
): void;

첫 번째 인자는 변경할 state를 전달하며, 두 번째 인자는 state가 변경 후 실행되는 callback 함수를 전달합니다. 

 

즉, state의 값을 변경 후 특정한 기능 또는 동작이 실행되도록 하고 싶다면, setState의 두 번째 인자인 callback 함수를 전달하면 됩니다.

 

다음 코드는 this.state.num의 값을 갱신 후 콘솔에 값을 출력하는 코드를 callback 함수로 전달합니다.

twiceButtonClick = () => {
  this.setState(
    { num: this.state.num * 2 }, 
    () => {
      console.log("state : " + this.state.num);
    }
  );
};

실행 결과

[* 2] 버튼을 클릭 전 결과입니다.

[* 2] 버튼 클릭 전

[* 2] 버튼을 클릭 후 결과입니다.

[* 2] 버튼 클릭 후

또 다른 방법으로는 생명주기 함수인 componentDidUpdate를 사용하는 것입니다.

twiceButtonClick = () => {
  this.setState({ num: this.state.num * 2 });
};
  
componentDidUpdate(prevProps, prevState) {
  if (this.state.num !== prevState.num) {
    console.log("state : " + this.state.num);
  }
}

이전 값과 현재 값을 비교해서 값이 일치하지 않으면, 특정 기능 또는 동작이 실행되는 코드를 작성합니다.


Function 컴포넌트의 setState Callback

React 16.8 이후 도입된 Hook은 useState 함수를 사용해서 state를 갱신할 수 있습니다.

 

단, useState 함수는 두 번째 인수가 존재하지 않습니다.

 

대신 useEffect에 선택적 인수로 두 번째 인수인 의존성 배열을 사용합니다.

 

다음은 위에서 작성한 Class 컴포넌트를 Hook으로 변경한 코드입니다.

function App() {
  const [num, setNum] = useState(1);

  function twiceButtonClick() {
    setNum(num * 2);
  }

  function initButtonClick() {
    setNum(1);
  }

  useEffect(() => {
    console.log("num : " + num);
  }, [num]);

  return (
    <div className="App">
      <button onClick={() => { twiceButtonClick(); }} >
        * 2
      </button>
      <button onClick={() => { initButtonClick(); }} >
        Clear
      </button>
      <div>{num}</div>
    </div>
  );
}

 

App 컴포넌트에서 핵심 코드는 useEffect 함수입니다.

useEffect(() => {
  console.log("num : " + num);
}, [num]);

두 번째 인자로 [num]을 전달하여 num이라는 state가 변경되면, useEffect 함수가 실행되도록 합니다.

반응형

댓글