react 기본 - 13.useEffect
useEffect
react Hook 중 useEffect는 컴포넌트가 렌더링 될 때마다 특정 작업을 실행할 수 있게 합니다.
마운트 될 때(처음 나타났을때), 언마운트 됐을 때(사라질때), 업데이트 될 때(특정 props가 바뀔 때) 특정 작업을 처리할 수 있습니다.
기본형태
useEffect(function, deps)
> function : 수행하고자 하는 작업
> deps : 배열 형태, 배열 안에는 검사하고자 하는 특정 값 or 빈 배열
**deps 를 생략한다면 렌더링 될 때 마다 실행됨**
1. 마운트 될 때
컴포넌트가 처음 나타날때에만 useEffect에 등록한 함수가 호출됩니다.
> props 로 받은 값을 컴포넌트의 로컬 상태로 설정
> 외부 API 요청
> 라이브러리 사용
> setInterval 을 통한 반복작업 혹은 setTimeout 을 통한 작업 예약
// useEffect 불러오기
import React,{useEffect} from 'react';
useEffect(() => {
console.log('마운트(처음) 될 때만 실행')
}, []);
2. 언마운트 될 때 & update 되기 직전에
cleanup 함수가 반환되며, useEffect에 대한 뒷정리 함수라고 생각하면 된다.
cleanup은 deps 가 비어있는 경우에는 컴포넌트가 사라질때 호출된다.
> setInterval, setTimeout 을 사용하여 등록한 작업들 clear(clearInterval, clearTimeout) 하기
> 라이브러리 인스턴스 제거
// useEffect 불러오기
import React,{useEffect} from 'react';
useEffect(() => {
console.log('user 값이 설정됨',user)
return () => {
console.log('user가 바뀌기 전',user)
}
}, []);
3. 업데이트 될 때
deps에 특정 값을 넣게 된다면, 컴포넌트가 처음 마운트 될 때와 지정한 값이 바뀔 때에도 호출이 됩니다.
useEffect에 deps를 넣지 않으면 useEffect에 등록한 함수가 실행 될 때 최신 props 상태를 가르키지 않습니다.
// useEffect 불러오기
import React,{useEffect} from 'react';
useEffect(() => {
console.log('user 값이 설정됨',user)
return () => {
console.log('user가 바뀌기 전',user)
}
}, [user]);
UserList.js
import React,{useEffect} from 'react';
const User = ({user, onRemove, onToggle}) => {
useEffect(() => {
console.log('user 값이 설정됨',user)
return () => {
console.log('user가 바뀌기 전',user)
}
}, [user]);
return(
<>
<p><b onClick={() => onToggle(user.id)} style={{cursor:'pointer', color: user.active ? 'green' : 'black'}}>{user.username}</b> "{user.email}" <button onClick={() => onRemove(user.id)} type="button">삭제</button></p>
</>
)
}
const UserList = ({users, onRemove, onToggle}) => {
return (
<>
{users.map(user => (
<User user={user} key={user.id} onRemove={onRemove} onToggle={onToggle}/>
))}
</>
)
}
export default UserList;
App.js
import React, {useRef, useState} from 'react';
import Inner from "./Inner";
import UserList from "./UserList";
import CreateUser from "./CreateUser";
function App() {
const [inputs, setInputs] = useState({
usersname: '',
email: ''
});
const {username, email} = inputs;
const onChange = e => {
const {name,value} = e.target;
setInputs({
...inputs,
[name]: value
});
}
const [users, setUsers] = useState ([
{
id: 1,
username: 'a',
email : 'aaa@gmail.com',
active: true
},
{
id: 2,
username: 'b',
email : 'bbb@gmail.com',
active: false
},
{
id: 3,
username: 'c',
email : 'ccc@gmail.com',
active: false
}
]);
const nextId = useRef(4);
const onCreate = () => {
const user = {
id: nextId.current,
username,
email
}
setUsers([...users, user]);
setInputs({
username: '',
email: ''
});
nextId.current += 1;
}
const onRemove = id => {
setUsers(users.filter(user => user.id !== id));
}
const onToggle = id => {
setUsers(
users.map(user => user.id === id ? {...user, active: !user.active} : user )
)
}
return (
<React.Fragment>
<Inner>
<CreateUser
username={username}
email={email}
onChange={onChange}
onCreate={onCreate}
/>
<UserList users={users} onRemove={onRemove} onToggle={onToggle}/>
</Inner>
</React.Fragment>
);
}
export default App;