함수가 함수 내부의 값 외에 외부의 값을 읽어오거나, 수정하는 행위
외부의 상태를 읽어올 때
const num = 1;
const sum = (x) => {
return x + num;
};
함수가 함수 내부의 값(local state)를 제외한 나머지 값(non local state)들을 읽어올 때 side effect가 있다고 말한다.
외부의 상태를 변경 시킬 때
함수가 함수 내부에 있는 값이 아닌, 외부의 값을 변경시킬 때 side effect가 발생했다고 말한다.
let num;
const sum = (x) => {
num = x + 1;
};
const changeTitle = (newTitle) => {
const title = document.getElementById('title');
title.innerText = newTitle;
};
const printNum = (x) => {
console.log(x);
};
Yes → 동작 결과를 예측하기 쉽지 않고 유지보수가 어렵기 때문이다.
그러나, 프로그래밍에서 외부의 값을 읽어오거나 변경하는 일은 완전히 배제할 수는 없다. 결론은 개발자가 side effect 최소화할 수 있게 설계해야한다.
프론트엔드 - 복잡한 UI를 구성, 변화시키는 데에 초점
백엔드 - 데이터를 저장하고 처리, 가공
⇒ React에서 DOM의 조작을 대신해주고 개발자는 UI와 핵심 로직에만 신경 쓴다. DOM에 직접 접근할 일이 많지 않고, 직접 조작하는 일은 권장하지 않는다. 단, DOM 직접 조작해야만 하는 특정 상황은 제외시킨다.
어떤 것의 변화를 계속해서 지켜보고 변화가 발생하면 특정한 액션을 취하는 것
setTimeout
: 일정 시간이 지나면 특정 동작을 수행setInterval
: 일정 시간마다 특정 동작을 수행React에서 side effect를 편리하고 안전하게 발생시킬 수 있게 도와주는 hook
useEffect(콜백 함수);
useEffect(콜백 함수, 의존성 배열);
import { useEffect } from 'react'
// 1. 의존성 배열이 전달되지 않았으므로 매 렌더링마다 side effect가 실행된다
useEffect(() => {
// side effect
});
// 2. 첫 번째 렌더링 이후에 side effect를 실행하고
// 그 이후에는 value 값이 변했을 때만 실행한다.
useEffect(() => {
// side effect
}, [value]);
// 3. 첫 번째 렌더링 이후에 side effect를 실행하고
// 그 이후에는 value1, value2 중 하나라도 변하면 side effect를 실행한다.
useEffect(() => {
// side effect
}, [value1, value2]);
// 4. 첫 번째 렌더링 이후에만 실행되고 그 뒤에는 실행되지 않는다
// 의존성 배열이 전달은 되었지만 배열 안에 값이 아무것도 없기 때문에
// 변화를 비교할 값이 없고 따라서 첫 번째 렌더링 이후에만 실행되고 그 뒤에는 실행되지 않는다.
useEffect(() => {
// data fetching side effect
}, []);
Mount
: 컴포넌트가 최초로 브라우저에 렌더링Side Effect
: useEffect 첫 번째 인자로 넘겨준 콜백 함수가 호출Update
: 컴포넌트의 state 또는 props가 변경되었을 경우 리렌더링이 발생의존성 배열
을 확인state
또는 props
가 변경된다면 → 3~4번의 과정을 반복 Unmount
: 컴포넌트가 더 이상 필요 없어지면 화면에서 사라진다불필요하게 계속해서 side effect가 남아있다면
useEffect에 전달한 콜백 함수에서 clean up을 하는 함수를 리턴
clean up 함수를 return만 해준다면 clean up 함수를 적절한 시점에 호출해 주는 일은 useEffect가 알아서 처리해준다.