React 에서 useEffect의 return 호출 조건이 이해가 안됩니다!

이번에 리액트 Hook 기능중에 useEffect를 배웠습니다.

그런데 제가 헷갈리는 게, useEffect에 함수를 정의할때 해당 함수가 return할 때의 코드가 일반적인 class기반 컴포넌트의 Lifecycle에서 componentWillUnmount와 같다고 설명하는데, 실제로 unmount 되지 않고 state가 변경될 때 마다 호출되고 있습니다.

class 기반 컴포넌트에서는 compoenetWillUnmount가 정말 컴포넌트가 렌더링 화면에서 사라질 때 호출되었는데 function 기반 컴포넌트에서 useEffect return이 호출되는 정확한 타이밍이 언제일까요?

제가 하도 이해가 안되서 같은 기능의 컴포넌트를 class방식과 function 방식으로 만들어봤습니다.

먼저 function 기반의 컴포넌트 입니다.

const App = () => {
    const [number, setNumber] = useState(0);
    useEffect(() => {
        console.log('component did mount with useEffect!');
        return () => {
            console.log("component will unmount");
        };
    }, [number]);
    return (
        <div>
            <h2>number is {number}</h2>
                <button
                    onClick={() => {
                        setNumber(number + 1);
                    }}
                >
                Increment
            </button>
        </div>
    );
};

이렇게 하면 버튼을 클릭 할 때마다 number state가 1씩 올라가고

콘솔창에는

component will unmount

component did mount with useEffect!

이렇게 표시가 됩니다. 즉 언마운트 되고 나서 갱신되는 것이 표현됩니다.

그리고 아래는 class 기반으로 만든 컴포넌트 입니다.

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { number: 0 };
  }
  componentDidMount() {
    console.log('component did mount');
  }
  componentDidUpdate() {
    console.log('component did update');
  }
  componentWillUnmount() {
    console.log('component will unmount');
  }
  render() {
    const { number } = this.state;
    return (
      <div>
        <h2>number is {number}</h2>
        <button
          onClick={() => {
            this.setState({ number: number + 1 });
          }}
        >
        Increment
        </button>
      </div>
    );
  }
}

제 생각에는 같은 기능을 하는 컴포넌트 입니다. 그런데 이 때는 클릭 할 때 마다

component did update

만 표시됩니다. 물론 componentDidUpdate를 없애면 콘솔에는 아무것도 출력되지 않습니다…

긴 글 읽어주셔서 감사합니다… 결론적으로 궁금한 건 useEffect에서 return이 호출되는 타이밍이 정말 컴포넌트가 언마운트 될 때가 맞는지… 그게 궁금하네요… 두 기능의 차이점을 정확히 알고싶어요 ㅠㅠ

[number] 대신에 [] 로 바꾸면 될거에요.

useEffect는 return값은 해당 effect가 더이상 실행할 필요가 없을 때 청소하는 용도입니다.
여기서 더 이상 실행할 필요가 없는 경우는 다음 두가지 입니다.

  1. dependancy(두번째 인자로 넘기는 배열)가 바뀌어서 effect가 달라져야할 때 (이전 effect 청소)
  2. 해당 component가 unmount 될 때

2번에 해당하는 unmount 될 때만 사용하려면 @choipd 님이 말씀하신 것처럼 dependancy가 항상 같도록 []를 넘기면 됩니다.