본문 바로가기

공부기록/[강의노트] Udemy React 완벽가이드 101~200

# 175 [udemy React 완벽 가이드 노트] 클래스 컴포넌트 Lifecycle

 클래스 베이스드 컴포넌트는 

useEffect 등의 React Hooks를 사용하지 않는다. 

 

모는 컴포넌트는 라이프 사이클이 존재한다. 

DOM에 render될때나 DOM에서 삭제될 때 등  

 

 

 

라이프 사이클안에서 다른 두 개의 시점에 코드를 실행할 수 있는 

클래스 컴포넌트에 추가할 수 있는 특정 메서드가 있다. 

 

클래스 컴포넌트에 추가할 수 있는 라이프사이클 메서드는 

ComponentDidMount가 있다.

 

extends 하게 되면 리액트에서 임포트 해서 사용할 수 있다. 

컴포넌트가 마운트 된 직후 리액트가 메서드를 호출할 것이다.

 

 또다른 라이프사이클 메서드는 

ComponentDidUpdate와

ComponentWillUnmount가 있다. 

 

이 세가지가 가장 자주 쓰이고 중요하다. 

 

 

ComponentDidMount


컴포넌트가 마운트 될 때

(컴포넌트가 평가되고 DOM에 렌더링될 때)

실행됨

기능은 useEffect (...,  [ ] )와 동일함 

 

 

ComponentDidUpdate


컴포넌트가 갱신될 때 호출됨

state등이 변경, 컴포넌트 재평가, 재렌더링 될 때 호출됨 

기능은 useEffect (...,  [someValue] )와 동일함 

 

 

ComponentWillUnmount


컴포넌트가 DOM에서 삭제되기 직전에 호출 

 

기능은 useEffect (()=> {return () => {...}}, [ ] )와 동일함 

cleanup 함수는 effect 함수가 다시 실행되기 직전에 호출, 

항상 컴포넌트가 DOM으로부터 삭제되기 전에 다시 호출됨

 

 

 

 

 함수형 컴포넌트를 클래스 기반 컴포넌트로 변경해보기 


import { Fragment, useState, useEffect, Component } from "react";

import Users from "./Users";
import classes from "./UserFinder.module.css";


const UserFinder = () => {
  const [filteredUsers, setFilteredUsers] = useState(DUMMY_USERS);
  const [searchTerm, setSearchTerm] = useState("");

  useEffect(() => {
    setFilteredUsers(
      DUMMY_USERS.filter(user => user.name.includes(searchTerm))
    );
  }, [searchTerm]);

  const searchChangeHandler = event => {
    setSearchTerm(event.target.value);
  };

  return (
    <>
      <div className={classes.finder}>
        <input type="search" onChange={searchChangeHandler} />
      </div>
      <Users users={filteredUsers} />
    </>
  );
};

export default UserFinder;

 

 

 

class UserFinder extends Component {
  constructor() {
    super();
    this.state = {
      filteredUsers: DUMMY_USERS,
      searchTerm: "",
    };
  }

  searchChangeHandler(event) {
    this.setState({
      searchTerm: event.target.value,
    });
  }

  componentDidUpdate() { 
    searchTerm
    this.setState({
      filteredUsers: DUMMY_USERS.filter(user => user.name.includes(searchTerm)),
    });
  }

  render() {
    return (
      <>
        <div className={classes.finder}>
          <input type="search" onChange={this.searchChangeHandler.bind(this)} />
        </div>
        <Users users={this.state.filteredUsers} />
      </>
    );
  }
}

 

 

 useEffect에서 componentDidUpdate로 변경할 때 무한루프


 

 그런데  useEffect에서 componentDidUpdate로 변경하면 

문제점이 있다. 무한루프에 빠지는 함정이다.

 

 

 

 

그래서 두 개의 인자를 넣어준다. 

현재 컴포넌트 갱신 직전 시점의 props와 스냅샷을 갖고 있는 인자다. 

 

 

    componentDidUpdate(prevProps, prevState) {
    if (prevState.searchTerm !== this.state.searchTerm) {
      this.setState({
        filteredUsers: DUMMY_USERS.filter(user =>
          user.name.includes(this.state.searchTerm)
        ),
      });
    }
  }

이렇게 되면 

setState를 호출하여 갱신되는 filteredUsers가 바뀌었다면, 

ComponentDidUpdate()메서드는 재실행되지만 

if 구문은 실행되지 않는다. 

 

그러면 무한루프가 발생하지 않게 되는 것이다. 

 

useEffect가 비교했을 때 좋다는 것을 알 수 있게 해주는 대목이다. 

짧고 dependencies를 명시하여 if문을 넣지 않아도 된다. 

즉, dependencies에 searchTerm을 넣어 이것이 변경된 경우에만 

리액트에 의해 실행되는 것이다.