[React에서 rendering이 발생하는 경우]
- 첫 리액트 앱을 실행했을 때
- 현재 리액트 내부에 어떤 상태(state)에 변경이 발생했을 때.
- 컴포넌트 내부 state가 변경되었을 때
- 컴포넌트에 새로운 props가 들어올 때,
여기서 Effect는 Side Effect와 동일한 의미를 지닌다.
React의 주요한 임무는 UI 렌더링이다. 유저가 키보드를 누르든 클릭을 하든, 입력에 반응하여 필요할 때 UI를 다시 렌더링한다.
Side Effect는 위에서 말한 React의 역할인 UI 렌더링에서 벗어난 모든 것들을 의미한다.
👉 Effect(Side Effect)란, 일반적인 React 컴포넌트 함수 밖에서 일어나는 일들
React 컴포넌트 안에 API 호출하는 부분이 있다면 어떻게 될까?
state가 변경될 때마다 컴포넌트가 rerendering함과 동시에 API호출을 또 하게 될 것이다. 이러면 성능저하는 물론이고, 잘못하면 버그나 무한루프가 발생할 수 있다.
이러한 Side Effect를 처리하기 위한 React Hook이 바로 useEffect() 이다.
useEffect( 함수, [ 의존성들-dependencies ] )
useEffect()는 두 개의 인수를 받는다.
- 함수
- 의존성 배열
첫 번째 인수로 주어질 함수 안에는 어떤 SideEffect 코드라도 넣을 수 있다.
이 함수는, 두 번째 인수로 주어질 [의존성 배열] 안에 담긴 값에 변경사항이 생길 경우에만 실행된다.
즉, 이 의존성 배열이 Side Effect가 실행될 타이밍을 알려준다고 할 수 있다.
만약 useEffect()가 포함된 컴포넌트가 rerendering 되더라도 이 함수는 실행되지 않는다. 오로지 [의존성 배열] 안에 담긴 값이 변경될 때만 실행된다.
useEffect( 함수 , [ ] )
만약 위처럼, 두 번째 인수에 [] 빈 배열이 주어진 경우엔, 처음 컴포넌트가 실행된 순간에만 useEffect() 내부의 함수가 실행된다.
그 이후에는 어떤 일이 있어도 함수가 실행되지 않는다.
딱 처음 컴포넌트가 실행될 때만 작동한다.
- 컴포넌트가 렌더링됨 (마운트)
- useEffect()의 첫 번째로 인수로 넘겨진 함수가 실행됨
2.1 이때 실행된 함수로 state, props가 변경된 경우, 컴포넌트 재렌더링- 대기 상태에서, useEffect()의 두 번째 인수로 넘긴 의존성 값들에 변경사항이 발생하는 지를 체크
- 변경사항이 발생하면 useEffect()의 첫 번째 인수로 넘겨진 함수가 실행됨
4.1 이때 실행된 함수로 state, props가 변경된 경우, 컴포넌트 재렌더링- 컴포넌트가 사라지면 같이 사라짐 (언마운트)
import React, { useState, useEffect } from "react";
function App() {
const [counter, setCounter] = useState(0);
const handleClick = () => setCounter((prev) => prev + 1);
console.log("i run all the time");
const iRunOnlyOnce = () => {
console.log("i run only once");
};
useEffect(iRunOnlyOnce, []);
return (
<div>
<h1>{counter}</h1>
<button onClick={handleClick}>Click Me!</button>
</div>
);
}
export default App;
위 코드를 실행하면 i run all the time
은 state가 변경될 때마다 실행되고
i run only once
는 한 번만 실행된다. (처음 실행될 때)
여기서 useEffect() 는 우리 코드가 딱 한번만 실행될 수 있도록 보호해준다.
import { useState, useEffect } from "react";
function App() {
const [counter, setValue] = useState(0);
const [keyword, setKeyword] = useState("");
const onClick = () => setValue((prev) => prev + 1);
const onChange = (event) => setKeyword(event.target.value);
useEffect(() => {
console.log("I run only once");
}, []); // 빈 배열일 때는 한 번만 실행된다. (ex API 호출)
useEffect(() => {
console.log("I run when 'keyword' changes.");
}, [keyword]); // keyword값이 update 될 때 실행된다 (맨 처음 포함)
useEffect(() => {
console.log("I run when 'counter' changes.");
}, [counter]); // counter값이 update 될 때 실행된다 (맨 처음 포함)
useEffect(() => {
console.log("I run when keyword or counter changes.");
}, [keyword, counter]); // keyword값 또는 counter값이 update 될 때만 실행된다 (맨 처음 포함)
return (
<div>
<input
value={keyword}
onChange={onChange}
type="text"
placeholder="Search Here..."
/>
<h1>{counter}</h1>
<button onClick={onClick}>welcome</button>
</div>
);
}
export default App;
useEffect(() => {}, [keyword]);
: keyword 값이 변화할 때마다 첫 번째 매개변수 함수가 실행된다.
useEffect(() => {}, [counter]);
: counter 값이 변화할 때마다 첫 번째 매개변수 함수가 실행된다.
useEffect(() => {}, [keyword, counter]);
: keyword 또는 counter 값이 변화할 때마다 첫 번째 매개변수 함수가 실행된다.
useEffect(() => { // 🔴 Avoid: Cleanup logic without corresponding setup logic return () => { doSomething(); }; }, []);
컴포넌트가 나타났을 때 (렌더링 됐을 때) useEffect의 effect 함수가 실행되고,
컴포넌트가 사라졌을 때 클린 업 (clean up) 부분이 실행된다.
클린 업은 useEffect 안에서 return 부분에 실행되길 원하는 함수를 넣으면 된다.
// App.jsx
import React, { useEffect } from "react";
const App = () => {
useEffect(()=>{
// 화면에 컴포넌트가 나타났을(mount) 때 실행하고자 하는 함수를 넣어주세요.
return ()=>{
// 화면에서 컴포넌트가 사라졌을(unmount) 때 실행하고자 하는 함수를 넣어주세요.
}
}, [])
return <div>hello react!</div>
};
export default App;
create 될 때 뿐만아니라 destroy 될 때도 무언가 동작하게 하고 싶다면 cleanUp을 활용하자.
import { useState, useEffect } from "react";
function Hello() {
useEffect(() => {
console.log("created :)");
return () => console.log("destroyed :("); // cleanUp 함수
}, []);
return <h1>Hello</h1>;
}
function App() {
const [showing, setShowing] = useState(false);
const onClick = () => setShowing((prev) => !prev);
return (
<div>
{showing ? <Hello /> : null}
<button onClick={onClick}>{showing ? "Hide" : "Show"}</button>
</div>
);
}
export default App;
Show 버튼 클릭 시 Hide 버튼으로 바뀌고 Hello 라는 문자가 나타난다.
Hide 버튼 클릭 시 Show 버튼으로 바뀌고 Hello 라는 문자가 사라진다.