Effect
함수에 속성이나 상태값을 사용한다면dependency
로 추가해야한다. 이 코드에서onConfirm
속성을 의존성으로 추가하려하는데onConfirm
은 함수
export default function DeleteConfirmation({ onConfirm, onCancel }) {
useEffect(() => {
console.log("TIMER SET");
const timer = setTimeout(() => {
onConfirm();
}, 3000);
return () => {
console.log("Cleaning up timer");
clearTimeout(timer);
};
}, [onConfirm]);
open
과 같은 의존성을이 배열에 추가할 때, 이 Modal 컴포넌트에서 리액트가 이 Effect 함수를 다시 실행해야 하기 때문
function Modal({ open, children, onClose }) {
const dialog = useRef();
useEffect(() => {
if (open) {
dialog.current.showModal();
} else {
dialog.current.close();
}
}, [open]);
//App.jsx
function handleRemovePlace() {
setPickedPlaces((prevPickedPlaces) =>
prevPickedPlaces.filter((place) => place.id !== selectedPlace.current)
);
setModalIsOpen(false);
const storedIds = JSON.parse(localStorage.getItem("selectedPlaces")) || [];
localStorage.setItem(
"selectedPlaces",
JSON.stringify(storedIds.filter((id) => id !== selectedPlace.current))
);
}
<Modal open={modalIsOpen}>
{modalIsOpen && (
<DeleteConfirmation
onCancel={handleStopRemovePlace}
onConfirm={handleRemovePlace}
/>
)}
</Modal>
js에서 함수는 객체이므로 이 handleRomovePlace
함수 객체로 앱 컴포넌트 함수가 실행될 때마다 재생성
그 이유는 앱 컴포넌트가 다시 렌더링될 때 함수가 다시 실행되면 완전히 새로운
handleRemovePlace
함수가 생성
이 함수를DeleteConfirmation
에서 받은 후에는 리액트는 이 새로운 값, 새로운 함수를 보고 이전의 값 또는 함수와 비교하게되고 둘이 다르다고 판단
무한루프 발생 위험
React에 함수가 항상 재생성되지 않도록 하기 위해 사용할 수 있는 hook이 제공 함수를 안에 넣어주기만 하면됨(첫번째인자) , 종속성(두번째인자)
- 둘러싼 함수를 return, 안쪽에 함수가 재생성되지 않고 내부에 메모리로서 저장
- 두번째인자:함수 안에 사용되는 prop또는 state value값 추가 (useEffect 유사)
const handleRemovePlace = useCallback(function handleRemovePlace() {
setPickedPlaces((prevPickedPlaces) =>
prevPickedPlaces.filter((place) => place.id !== selectedPlace.current)
);
setModalIsOpen(false);
const storedIds = JSON.parse(localStorage.getItem("selectedPlaces")) || [];
localStorage.setItem(
"selectedPlaces",
JSON.stringify(storedIds.filter((id) => id !== selectedPlace.current))
);
}, []);