클래스형 컴포넌트는 사실 기초 셋업이 조금 복잡하다. 따라서 , 간단하게 컴포넌트를 만들고 싶을때는 함수형을 사용한다. 그러나 함수형이 이전 리액트에서는 state가 없어서 한계가 있었다.
그러나 Hook이라는 게 나오면서 함수형에서도 state나 클래스컴포넌트가 가진 다양한 기능들을 사용할 수 있게 되었다.
일단, Hook은 뭔가? lovely Colt는 "Hooks allow you to hook
into internal working of react"라고 한다. 리액트가 제공하는 다른 내부 부품들을 사용할 수 있게 하는 메소트, 함수를 의미한다고 보면 된다.
클래스 컴포넌트 처럼 setState를 호출하면 리랜더링 한다.
Hook은 조건문, 반복문처럼 스코프안에 깊숙히 있으면 오류가 날 수 있다. 함수 최상단 스코프에 선언하는게 안전하다. 참고
그럼 버튼을 클릭했을때 숫자가 하나씩 증가하는 함수를 useState라는 Hook을 사용해서 만들어보겠다.
import { useState } from 'react';
import ReactDOM from 'react-dom';
import UseStatePractice from './UseStatePractice'
ReactDOM.render(
<UseStatePractice justProps="ppp" />,
document.querySelector('#root')
);
//컴포넌트는 항상 대문자로 시작해야한다. 소문자로 시작하면 DOM으로 인식할것이다.
function UseStatePractice(props) {
const [count, setNumber] = useState(0);
const [name, setName] = useState(null);
const handleCount = () => {
setNumber(count + 1);
};
const handleName = evt => {
setName(evt.target.value);
};
console.log(props.justProps);
return (
<div>
<h1>{count}</h1>
<h1>{name}</h1>
<button onClick={handleCount}>Increase Count</button>
<input onChange={handleName} placeholder="Change Name" />
</div>
);
}
useState는 state 변수와, setState함수를 리턴한다. array 형태로 리턴되기에 네이밍은 마음대로 해도 상관없다. 그리고 state를 하나더 추가하고 싶으면 useState를 한번 더 호출하면 된다. 클로져로 작동되기에 각각의 state가 독립적으로 관리된다.
useState를 이용해서 custom state를 만들어 더욱더 코드를 간소화 시킬 수 있다. 다음 글에서 알아보자.
+++ 근데 함수형 컴포넌트는 리랜더링 될때마다 컴포넌트안에 있는 다른 함수까지 평가되면서 코드를 읽고 계산한다. 즉 랜더링만 하면 되는데 안에 있는 다른 함수들(클래스로 따지만 메소드)까지 매번 다시 생성되는 것이다.
근데 클래스 컴포넌트는 한번 메소드가 만들어지면 같은 reference에 그대로 유지됨.
즉 , React.memo 나 PureComponent로 리랜더링을 방지하려고 할 때 , 함수 컴포넌트의 경우, 새롭게 생성되는 함수들로 인해서 리랜더링방지가 실패될 수 있다.(이는 arrow function을 prop으로 넘길때 리랜더링이 일어나지 않는 이유와 비슷한것 같다.)
물론 함수형 컴포넌트에서 useCallBack, useEffect 같은것으로 함수의 재 평가를 트리거 하지 않을 수 있지만 기본적으로는 일단 이렇다는 것을 알아두자.
+++ setState에 이전과 같은 value를 pass하면 리랜더링 되지 않는다.(instagram clone에서 profile - carousel을 구현하면서 알게된 사실)