클래스 베이스드 컴포넌트는
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을 넣어 이것이 변경된 경우에만
리액트에 의해 실행되는 것이다.
'공부기록 > [강의노트] Udemy React 완벽가이드 101~200' 카테고리의 다른 글
# 179 [udemy React 완벽 가이드 노트] 클래스 기반 컴포넌트를 써야할 때 : Error Boundaries (try-catch 문) (1) | 2022.09.30 |
---|---|
# 177 [udemy React 완벽 가이드 노트] 클래스 컴포넌트와 컨텍스트 (1) | 2022.09.30 |
# 174 [udemy React 완벽 가이드 노트] class기반 컴포넌트에서 state및 이벤트 작업하기 (0) | 2022.09.29 |
# 173 [udemy React 완벽 가이드 노트] class-based Component: 함수형의 대안 (0) | 2022.09.29 |
# 169 [udemy React 완벽 가이드 노트] useMemo (1) | 2022.09.29 |