10-1. Basic
- 리액트 16.8에서 새로 도입된 기능
- 함수 컴포넌트에서 사용 불가능한 생명 주기 메소드의 한계점으로 인해 상태 관리 및 랜더링 이후 시점 컨트롤 등 다양한 문제를 해결하기 위해 만든 함수 집합
- 클래스형 컴포넌트에서는 컴포넌트 랜더링 후 특정 작업 수행 시 componentDidMount 혹은 componentDidUpdate 메소드를 사용
- 함수형 컴포넌트에서는 생명주기 api를 사용할 수 없으므로 제공되는 hook 활용
const {useEffect} = React;
function MessagePrinter(props){
console.log('랜더링...');
useEffect(() => {
console.log('랜더링 이후 동작');
});
return (
<h1>{console.log('랜더링 시 출력')}{props.message}</h1>
);
}
const message = '안녕하세요';
ReactDOM.createRoot(document.getElementById('root')).render(
<MessagePrinter message={message}/>
)
10-2. Mount
- useEffect는 기본적으로 마운트 된 시점, 업데이트 된 시점 두 가지 모두 동작
- 마운트 될 때만 동작하고 업데이트 시에는 동작하지 않도록 컨트롤 가능
const {useState, useEffect} = React;
function TimePrinter() {
const [time, setTime] = useState(new Date().toLocaleTimeString());
useEffect(
() => {console.log('useEffect 동작')},
[]
);
return (
<>
<button onClick={ () => setTime(new Date().toLocaleTimeString())}
> 현재 시간 확인
</button>
<h1>{ time }</h1>
</>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<TimePrinter/>);
10-3. Update
- 특정 값이 업데이트 될 때만 실행하게 컨트롤
- 업데이트시에만 동작하는 것이 아니므로 최초 마운트 시점에도 동작
const {useState, useEffect } = React;
function LoginForm(){
const [user, setUser] = useState({
username : '',
password : ''
});
const onChangeHandler = (e) => {
setUser({
...user,
[e.target.name] : e.target.value
});
}
useEffect(() => {
console.log('username update...')},
[user.username]
);
useEffect(() => {
console.log('password update...')},
[user.password]
);
return(
<>
<label>username : </label>
<input type="text" name="username" onChange={onChangeHandler}/><br/>
<label>password : </label>
<input type="password" name="password" onChange={onChangeHandler}/>
<h3>username : {user.username}</h3>
<h3>password : {user.password}</h3>
</>
);
}
ReactDOM.createRoot(document.getElementById("root")).render(<LoginForm/>);
10-4. CleanUp
- useEffect는 기본적으로 렌더링 직후, 업데이트 직후 호출
- 컴포넌트가 마운트 해제 되기 직전, 업데이트 되기 직전에 실행할 내용이 있다면 정리(clean up) 하는 기능도 수행 가능
- 이전 effect 내용을 정리하고 난 뒤 새로운 effect가 동작하도록 할 때 실행
- 이전 effect가 남아있는 상태에서 새로운 effect가 발생하면 메모리 누수나 충돌이 발생할 가능성 있음(componentWillUnmount의 역할과 동일)
const { useState, useEffect } = React;
function Counter(){
const [count, setCount ] = useState(0);
useEffect(() => {
console.log('useEffect 동작');
return () => {
console.log('clean-up')
}
});
return (
<>
<h1> count : {count}</h1>
<button
onClick = { () => setCount(count + 1) }
> +1 </button>
</>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<Counter/>)
클린업 예제
https://gitlab.com/java702/11.react/react/-/blob/main/03_hooks/01_useEffect/05_useEffect-cleanup-example.html
타이핑 게임
https://gitlab.com/java702/11.react/react/-/blob/main/03_hooks/01_useEffect/06_typing-game-example.html