전 포스팅에서 memo를 언급했었다.
state가 하나라도 바뀌면 컴포넌트 자체가 통째로 리렌더링 되는 상황때문에 사용하는 기능이었다.
effect는 memo와 아주 흡사한 기능이다.
effect는 실행 시점을 결정한다.
import { useState, useEffect } from "react";
function App() {
const [counter, setValue] = useState(0);
const onClick = () => setValue((prev) => prev + 1);
console.log("i run all the time");
useEffect(() => {
console.log("CALL THE API...");
}, []);
return (
<div>
<h1>{counter}</h1>
<button onClick={onClick}>click me</button>
</div>
);
}
export default App;
이 예제코드의 초기 화면에서는 콘솔에 찍은 i run all the time 과 CALL THE API 가 둘 다 나타난다.
버튼을 눌러보면 effect가 적용된 CALL THE API는 더이상 콘솔에 찍히지 않는 것을 확인할 수 있다.
useEffect(() => {
console.log("CALL THE API...");
}, []);
전 강의에서는 effect의 모든 기능을 사용한 건 아니었다.
실행할 소스를 적는 부분 말고도 배열을 담는 부분이 있었기 때문이다.
이번 강의에서는 effect의 기능을 완전히 알아볼 것이다.
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);
console.log("i run all the time");
useEffect(() => {
console.log("CALL THE API...");
}, []);
useEffect(() => {
console.log("SEARCH FOR", keyword);
}, [keyword]);
return (
<div>
<input onChange={onChange} type="text" placeholder="Search here..." />
<h1>{counter}</h1>
<button onClick={onClick}>click me</button>
</div>
);
}
export default App;
위와 같이 소스를 입력하면
인풋박스에 글자를 입력할 때마다 console.log("SEARCH FOR", keyword);
이 작동한다.
이렇게 인터렉티브하게 작동할 수 있는 이유는 effect의 [] 안에 state로 선언해준 keyword가 있기 때문이다.
useEffect(() => {
console.log("SEARCH FOR", keyword);
}, [keyword]);
여기서 [] 의 역할은 react가 []속에 든 인자를 감시하여 변화가 있을 경우에만 effect 안에 적은 소스를 작동시키는 것이다.
useEffect(() => {
console.log("CALL THE API...");
}, []);
그렇기 때문에 아무것도 적지 않은 채 []로 빈칸을 만들어놨을 경우 effect가 한 번만 실행되는 것이다.
(react가 아무것도 감시하지 않기 때문에 태초에 한 번 실행되고 끝나는 것!)
useEffect(() => {
if (keyword !== "" && keyword.length >= 5) {
console.log("SEARCH FOR", keyword);
}
}, [keyword]);
위와 같이 조건을 추가할 수도 있다.
5글자 이상인 경우에만 console.log("SEARCH FOR", keyword);
이 작동하여 '안녕하세요'로 완성된 문장이 콘솔에 뜨게 된다.
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("CALL THE API...");
}, []);
useEffect(() => {
if (keyword !== "" && keyword.length >= 5) {
console.log("SEARCH FOR", keyword);
}
}, [keyword]);
useEffect(() => {
console.log("I run when 'keyword' changes");
}, [keyword]);
useEffect(() => {
console.log("I run when 'counter' changes");
}, [counter]);
useEffect(() => {
console.log("I run when 'keyword & counter' changes");
}, [keyword, counter]);
return (
<div>
<input onChange={onChange} type="text" placeholder="Search here..." />
<h1>{counter}</h1>
<button onClick={onClick}>click me</button>
</div>
);
}
export default App;
useEffect를 여러 개 추가해주었다.
위처럼 다양한 인자를 넣어서 사용할 수 있는데, 특히 keyword, counter 두 개의 state를 인자로 받은 것이 위 소스의 핵심 포인트다.
버튼을 클릭했을 시 콘솔창
인풋창에 글자 입력 시 콘솔창
clean up이란, effect로 호출한 기능이 종료되는 시점에 특정 기능을 호출하는 기능이다.
생각보다 아주 간단하다.
import { useState, useEffect } from "react";
function Hello() {
useEffect(() => {
console.log("hi :)");
return () => console.log("bye :(");
}, []);
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;
위 소스 중 App 컴포넌트는 Show 버튼을 눌렀을 때 onClick 이벤트가 발동되어 showing state를 false에서 true로 만들어주고, 버튼의 벨류값을 Show 에서 Hide로 바꾸어주는 소스이다.
Hello 컴포넌트는 effect가 사용되어 Hello가 App에서 호출될 때 바로 발동되고, (이때, 호출되는 시점은 showing state가 true 일 때이다)
다시 한 번 버튼을 눌러 showing state의 값이 false가 될 때 Hello 컴포넌트는 종료된다.
그리고 이 clean up 시점에서 console.log("bye :(");
가 발동된다.
이 소스에서 clean up에 해당하는 부분이 바로
return () => console.log("bye :(");
}, []);
이 부분이다.
clean up은 effect가 발동되는 코드를 작성한 뒤에 return을 적고 함수를 하나 더 만들어서 거기에 코드를 작성해주면 된다.
이 clean up 기능은 생각보다 잘 쓰이지 않는다고 한다.
이로써 react의 기초적인 이론은 모두 끝이 났다.
수고한 내 자신과 니꼬쌤에게 박수...