function component는 state를 사용하지 못하고, Lifecycle에 따른 기능 구현이 불가능하다
대신 Hooks를 이용하면 class component의 기능을 모두 이용할 수 있다
useState()
state를 사용하기 위한 Hook
const [변수명, set함수명] = useSteate(초기값);
클래스 컴포넌트에서는 setState()를 사용해서 state를 한번에 모두 변경할 수 있지만,
함수 컴포넌트에서는 useState()를 각각 일일이 사용해야 한다
변수 각각에 대해 함수가 따로 있다.
state를 변경할때 새로 변경할 state값이 이전 state값과 연관되어있다면 setState의 인자로 새로운 state값을 리턴하는 콜백함수를 쓰는것이 좋다
setState((prevState) => {
// ...
return newState;
});
useState를 사용해서 초깃값을 받아올때 그 작업이 무거운 작업이라면 useState의 인자로 콜백함수를 넣어주면 맨처음 렌더링이 될때만 실행된다.
useState(() -> {
return heavyWroks();
})
리액트에서 state 값이 변경되면 해당 컴포넌트가 재 렌더링 된다.
useEffect()
리액트의 함수 컴포넌트에서 Side effect를 실행할 수 있게 해주는 Hook
useEffect() Hook 만으로 클래스 컴포넌트의 생명주기 함수 3개와 동일한 기능이 가능하다.
useEffect(이펙트 함수, 의존성 배열);
useEffect(() => {
// 컴포넌트가 마운트 된 이후,
// 의존성 배열에 있는 변수들 중 하나라도 값이 변경되었을떄 실행 됨, 첫 렌더링 될때도 실행됨
// 의존성 배열에 빈 배열([])을 넣으면 마운트(첫 렌더링)될때만 실행
// 의존성 배열 생략시 컴포넌트 업데이트 시마다 실행됨
return () => {
// 컴포넌트가 마운트 해제되기 전에 실행됨
}
}, [의존성 변수1, 의존성 변수2]);
useMemo()
여기서 memo는 memoization의 memo
const memoizedValue = useMemo(
() => { // 연산량이 높은 작업을 수행하여 결과를 반환
return computeExpensiveValue(의존성 변수1, 의존성 변수2);
},
[의존성 변수1, 의존성 변수2]
);
useMemo()로 전달된 함수는 렌더링이 일어나는 동안 실행된다
결과적으로 빠른 렌더링 속도를 얻을 수 있다
이말은 렌더링이 일어날동안 실행되서는 안되는 작업을 useMemo()에 넣으면 안된다 -> useEffect()에서 일어나야할 Side Effect 같은 것들(서버에서 데이터를 받아오는 것, 수동으로 돔을 변경하는 것)
의존성 배열을 넣지 않을 경우, 매 렌더링마다 수행됨
빈배열을 넣으면, 컴포넌트 마운트 시에만 호출 됨
useCallback()
useMemo() Hook과 비슷하지만 값이 아닌 함수를 반환
의존성 변수의 값이 바뀔 때마다 함수를 새로 정의
const memoizedCallback = useCallback(
() => {
doSomething(의존성 변수1, 의존성 변수2);
},
[의존성 변수1, 의존성 변수2]
)
useRef()
Reference를 사용하기 위한 Hook
Reference - 특정 컴포넌트에 접근할 수 있는 객체
useRef() Hook은 매번 렌더링 될때마다 항상 같은 레퍼런스를 return한다
useRef() Hook은 내부의 데이터가 변경되었을 때 별도로 알리지 않는다
ref는 하나의 오브젝트(키/값)
state가 변한다면 렌더링 될때마다 컴포넌트 내부 변수들이 초기화된다.
하지만 Ref가 변해도 렌더링이 되지 않기 때문에 변수들의 값이 유지된다.
-> 불필요한 렌더링을 막을수있다. state가 변해도 ref의 값은 유지된다.
ref는 변화를 감지해야하지만, 그 변화때문에 렌더링이 되면 안될때 사용한다.
일반 변수는 렌더링될때마다 초기화 된다. 하지만 ref는 해당 컴포넌트가 처음 마운트 됐을때부터 아예 없어질때까지 계속 유지된다.
ref를 이용해서 DOM 요소에 접근하여 여러가지 일을 할 수 있다.
ex) 로그인창 띄우고 아이디칸에 커서 띄우는 것
useContext
이걸 사용하면 로그인 유저 정보, 다크모드 체크 등등 굳이 중간 페이지가 확인할필요없는 정보들을 자식들에게 보내주기 위해서 props로 일일이 보내줄 필요없음
useReducer()
userState()는 변수하나마다 다 선언해줘야함.
그리고 해당 값이 바뀔때마다 컴포넌트가 재렌더링됨
useReducer를 쓴다면 내가 원할때 업데이트 시켜 렌더링시킬수있고, 많은 변수를 한번에 관리할수있다.
1.Hook은 무조건 '최상위 레벨'에서만 호출해야 한다
Hook은 컴포넌트가 렌더링될 때마다 매번 같은 순서로 호출되어야 한다
if문이나 반복문에서 Hook을 호출하면 안된다
2.리액트 '함수 컴포넌트'에서만 Hook을 호출해야 한다
커스텀 훅의 이름은 무조건 use로 시작해야 한다.