button을 클릭 할때마다 onClick 이벤트에 의해서 setCounter가 호출 된다.
- 이말은 즉슨 App컴포넌트가 리랜더링 된다는 것!
- 리랜더링 되면 내가 딱 한번만 호출하고 싶은 함수가 있을 때 단점이 될 수 있다.
- 예를들어 API를 딱 한번만 호출하고 그 뒤로는 다시 호출하기 싫은 경우
function App() {
const [counter, setCounter] = useState(0);
const onClick = () => setCounter(prev => prev + 1);
console.log("l run all the time");
console.log("i run only one");
return (
<div>
<h1>{counter}</h1>
<button onClick={onClick}>Button</button>
</div>
);
}
useEffect는 두개의 argument를 받는다 .
- 첫번째 argument는 callback함수로 우리가 딱 한번만 실행하고 싶은 코드를 넣으면 된다.
- 두번째 argument는 배열이다.
- 빈배열로 나두면 callback함수가 처음에 컴포넌트가 실행될 때 딱 한번 실행된다
- 배열안에 useState의 0번째 인덱스 값 (counter)을 넣어주면 setCounter기 실행 될 때만 callback함수가 실행된다. (물론 처음 컴포넌트가 실행될 때 도 실행된다.)
import { useState, useEffect } from "react";
function App() {
const [counter, setCounter] = useState(0);
const onClick = () => setCounter(prev => prev + 1);
console.log("l run all the time");
useEffect(() => {
console.log("i run only one");
}, []);
return (
<div>
<h1>{counter}</h1>
<button onClick={onClick}>Button</button>
</div>
);
}
useEffect의 두번째 argument를 쓰는경우
setKeyword가 실행될 때 즉 onChange가 실행 될 때 만 console.log("SEARCH FOR", keyword)가 실행 된다.
import { useState, useEffect } from "react";
function App() {
const [counter, setCounter] = useState(0);
const [keyword, setKeyword] = useState("");
const onClick = () => setCounter(prev => prev + 1);
const onChange = e => setKeyword(e.target.value);
console.log("l run all the time");
useEffect(() => {
console.log("i run only one");
}, []);
useEffect(() => {
console.log("SEARCH FOR", keyword);
},[keyword]);
return (
<div>
<input
value={keyword}
onChange={onChange}
type="text"
placeholder="Search here"
/>
<h1 className={styles.title}>{counter}</h1>
<button onClick={onClick}>Button</button>
</div>
);
}
useEffct의 첫번째 argument에 리턴값으로 콜백함수를 주면 해당 콜백함수는 컴포넌트가 파괴 될때 콜백함수가 실행된다.
function Hello() {
useEffect(() => {
console.log("Created :)");
return () => console.log("Destroyed :)");
}, []);
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>
);
}