https://www.youtube.com/watch?v=kyodvzc5GHU 처음 공부하시는 거라면 이 영상 추천드립니다.
1. useEffect란?
mount , update, unmount 될 때, 특정 작업을 실행해주고 싶을 때 사용하는 훅
이때 useEffect는 주로 함수내에 넣는데 이 이유는 공식 문서에서 다음과 같이 나온다.
--------
useEffect구성 요소 내부에서 호출되는 이유는 무엇 입니까? useEffect구성 요소 내부에 배치 count하면 효과에서 바로 상태 변수(또는 모든 소품)에 액세스할 수 있습니다. 이를 읽기 위해 특별한 API가 필요하지 않습니다.
---------
2. useEffect의 형태
useEffect = (()=> {
//기본형태 콜백함수를 가짐
} )
//,.....
useEffect = (()=>{
// value일 때만 작동
},[value])
기본적으로 콜백함수를 가진 형태를 띔
첫 번째 경우는 랜더링시 마다 useEffect 내부의 함수를 실행합니다.
하지만 매 랜더링마다 특정함수를 사용하게 되면, 리소스를 너무 많이 소비하게 됩니다.
이때 아래의 경우처럼 2번째 인자로 최적화가 가능합니다.
두 번째 useEffect 의 경우에 [value]를 두 번째 인자로 받고 있습니다.
이 배열은 디펜던시 어레이라고 부르며, 아래의 useEffect는 마운트 될 때, 두 번 배열속의 value 값이 바뀔 때 실행합니다.
예시 ) 항해 심화주차 counter를 통해서
// src/App.jsx
import React, { useEffect, useState } from "react";
import axios from "axios";
const App = () => {
const [todo, setTodo] = useState({
title: "",
});
const [todos, setTodos] = useState(null);
// patch에서 사용할 id, 수정값의 state를 추가
const [targetId, setTargetId] = useState(null);
const [editTodo, setEditTodo] = useState({
title: "",
});
const fetchTodos = async () => {
const { data } = await axios.get("http://localhost:3001/todos");
setTodos(data);
};
const onSubmitHandler = async (todo) => {
const { data } = await axios.post("http://localhost:3001/todos", todo);
setTodos([...todos, data]);
};
const onClickDeleteButtonHandler = async (todoId) => {
await axios.delete(`http://localhost:3001/todos/${todoId}`);
setTodos([...todos]);
// fetchTodos();
};
// 수정버튼 이벤트 핸들러 추가 👇
const onClickEditButtonHandler = (todoId, edit) => {
axios.patch(`http://localhost:3001/todos/${todoId}`, edit);
fetchTodos();
};
// // 무한 랜더링이 됨 why? fetchTodos안에 setTodos가 todos의 state를 바꾸기 때문에, 랜더링 일어나고, 랜더링시 다시 useEffect
// useEffect(() => {
// fetchTodos();
// });
/////마운트 시에만 사용
// useEffect(() => {
// fetchTodos();
// }, []);
useEffect(() => {
fetchTodos();
}, [todos]);
return (
<>
<form
onSubmit={(e) => {
e.preventDefault();
onSubmitHandler(todo);
}}
>
{/* 👇 수정기능에 필요한 id, 수정값 input2개와 수정하기 버튼을 추가 */}
<div>
<input
type="text"
placeholder="수정하고싶은 Todo ID"
onChange={(ev) => {
setTargetId(ev.target.value);
}}
/>
<input
type="text"
placeholder="수정값 입력"
onChange={(ev) => {
setEditTodo({
...editTodo,
title: ev.target.value,
});
}}
/>
<button
// type='button' 을 추가해야 form의 영향에서 벗어남
type="button"
onClick={() => onClickEditButtonHandler(targetId, editTodo)}
>
수정하기
</button>
</div>
<input
type="text"
onChange={(ev) => {
const { value } = ev.target;
setTodo({
...todo,
title: value,
});
}}
/>
<button>추가하기</button>
<button>추가하기</button>
<button>추가하기</button>
</form>
<div>
{todos?.map((todo) => (
<div key={todo.id}>
{/* todo의 아이디를 화면에 표시 */}
{todo.id} :{todo.title}
<button
type="button"
onClick={() => onClickDeleteButtonHandler(todo.id)}
>
삭제하기
</button>
</div>
))}
</div>
</>
);
};
export default App;
하지만 위의 2경우에 경우를 통해서 함수를 실행했을 때, 그 함수를 종료하는 기능이 없다.
이때 구독했던 함수를 종료하는 것을 Clean up이라고 한다.
useEffect = (() => {
//구독하기
return ()=> {
//구독해지
}
},[])
참고자료 : https://reactjs.org/docs/hooks-effect.html
Using the Effect Hook – React
A JavaScript library for building user interfaces
reactjs.org
'TIL > React' 카테고리의 다른 글
[React 함수형] Modal을 이용해서 팝업창 띄우기 (1) | 2023.01.14 |
---|---|
리액트 라이프 사이클 클래스형 vs 함수형 (2) | 2023.01.09 |
[React]훅 -useRef (0) | 2023.01.08 |
[ Redux toolkit] export 되는 과정 (0) | 2023.01.08 |