const [state변수이름, set + state 변수이름] = useState(초기값);
[]
의미는 배열 구조 분해 문법(구조 분해 할당)과 연관)import React, {useState} from "react";
const [count, setCount] = useState(0);
//count는 state 변수명, setCount는 state를 업데이트하는 함수
<p>It is {count}</p>
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
side effect를 이해하려면 먼저 자바스크립트의 "순수 함수" 개념에 대한 이해가 필요
side effect 출처: https://dev.to/ruizb/side-effects-21fc
useEffect 설명은 다음 글에서 더 자세히 다룰 예정!
function exFunc() {
const [isClicked, setIsClicked] = useState(false);
useEffect(() => {
console.log("isClicked changed!");
}, [isClicked]);
useEffect(() => {
console.log("exFunc first rendering");
}, []);
return <button onClick={() => setIsClicked(!isClicked)}>click</button>
}
이 exFunc 함수 컴포넌트 첫 렌더링 후 버튼을 클릭 시 렌더링 되는 과정은 다음과 같다
//첫번째 렌더링
useState(false) //isClicked가 false으로 초기화
useEffect(...console.log("isClicked changed!")) //console에 "isClicked changed!" 출력
useEffect(...console.log("exFunc first rendering)) //console에 "exFunc first rendering" 출력
//hook 순서: useState -> useEffect -> useEffect로 기억
//버튼 1회 클릭 후
useState(1) //isClicked가 true로 초기화
useEffect(...console.log("isClicked changed!")) //console에 "isClicked changed!" 출력
useEffect(...console.log("exFunc first rendering)) //console에 "exFunc first rendering" 출력
그럼 두번째 useEffect를 조건문으로 감싼 exFunc2로 규칙을 깨면 어떤 현상이 발생하는지 알아보자
function exFunc2() {
const [isClicked, setIsClicked] = useState(false);
if (isClicked < 1) {
useEffect(() => {
console.log("isClicked changed!");
}, [isClicked]);
}
useEffect(() => {
console.log("exFunc first rendering");
}, []);
return <button onClick={() => setIsClicked(!isClicked)}>click</button>
}
이 컴포넌트가 첫 렌더링 한 후 버튼을 클릭하면 어떻게 될까?
//첫번째 렌더링
useState(0) //clickedNum이 0으로 초기화
useEffect(...console.log("isClicked changed!")) //console에 "isClicked changed!" 출력
useEffect(...console.log("exFunc first rendering)) //console에 "exFunc first rendering" 출력
//hook 순서: useState -> useEffect -> useEffect로 기억
//버튼 1회 클릭 후
useState(1) //clickedNum이 1로 초기화
XXX useEffect(...console.log("button is clicked!")) XXX //isClicked가 1이 되었으므로 pass!
useEffect(...console.log("exFunc first rendering)) //기억한 hook의 순서가 달라져 실행 실패
예시 참고: https://velog.io/@humonnom/Hook-Hook%EC%9D%98-%EA%B7%9C%EC%B9%991
hook순서가 기억된 대로 실행을 하지 않으면 오류가 나기 때문에 조건문, 반복문, 중첩 함수 등 내부에 hook을 사용하면 안된다.
useEffect에 조건문을 써야할 때가 있는데 그러면 useEffect 안에서 조건문을 사용하면 된다.