surf react : hooks (useState, useEffect) - 2
🔔 Goal
- react hooks의 useState를 이해한다.
- react hooks의 useEffect를 이해한다.
🌳 useState
useState는 함수형 컴포넌트에 state를 제공한다.
initialState를 파라미터로 받고, state와 state를 변경할 setState 함수를 반환한다.
import { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
return (
<div>
<p>{`count: ${count}`}</p>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
</div>
)
};
export default Counter;
useState가 반환하는 첫 번째 인자인 state와 두 번째 인자인 setState를 비구조화 할당 문법을 통해 count, setCount로 받아서 사용할 수 있게 된다.
setCount로 count state를 변경하면 리렌더링된다.
Counter는 함수이기 때문에, 렌더링 할 컴포넌트 대신에 값을 반환할 수도 있다.
import { useState } from 'react';
const useCount = (gap) => {
const [count, setCount] = useState(0);
const increaseCount = () => {
setCount(count + gap);
}
const decreaseCount = () => {
setCount(count - gap);
}
return [
count,
increaseCount,
decreaseCount,
]
}
export default useCount;
위 예제가 바로 Custom Hook을 만든 것이다. 이 useCount를 원하는 컴포넌트에서 호출하면 state인 count 값을 이용할 수 있고, setCount를 실행하도록 만들어진 increaseCount나 decreaseCount로 state를 변경할 수 있게 된다.
use~는 Custom Hook의 naming rule이다. 이 rule을 지키면 lint에서 hooks와 관련된 규칙들을 점검해줄 수 있기 때문에 따르는 것을 권장한다.
🌳 useEffect
클래스 컴포넌트에 제공되었던 Life Cycle API는 useEffect로 사용할 수 있다.
Life Cycle API에서 우리가 수행했던 API 요청, DOM 조작 등이 side effect이기 때문에, useEffect라는 이름의 API가 되었다고 한다.
클래스 컴포넌트에서의 componentDidMount, componentDidUpdate, componentWillUnmount가 useEffect로 실행된다.
function useEffect(effect: EffectCallback, inputs?: InputIdentityList)
render가 발생할 때 마다(componentDidMount: 초기, componentDUpdate: 매번) effect가 실행된다.
두 번째 파라미터인 inputs를 통해 특정한 상태가 update 되었을 때만 effect가 실행되도록 설정할 수도 있다.
import { useState, useEffect } from 'react';
export function Data() {
const [data, setData] = useState(null);
useEffect(() => {
API.getData()
.then((response) => { setData(response) });
}, []);
const isLoading = (data == null);
if (isLoading) {
return 'Loading..';
}
return data;
}
위 예제는 useEffect의 inputs에 빈 배열을 넘겨서 최초(componentDidMount)에만 실행되도록 했다. useEffect는 여러 개 사용할 수 있기 때문에 각 state마다 관심사를 분리할 수 있고, 예제처럼 최초에 실행되는 것만 정의해주어도 된다.
그럼 componentWillUnmount는 어떻게 실행할까
useEffect(() => {
window.addEventListener("mousemove", logMousePosition);
return () => {
window.removeEventListener("mousemove", logMousePosition);
};
}, []);
effect 함수의 return 값이 있는 경우 hook의 cleanup 함수로 인식하고 다음 effect가 실행되기 전에 실행해준다.
componentWillUnmount는 컴포넌트가 사라지기 전에 한 번만 실행했지만, cleanup 함수는 새로운 effect 실행 전에 매번 호출된다는 차이가 있다.
위 예제코드에서는 inputs로 빈 배열을 넘겨주었기 때문에 unmount 될 때 한 번만 실행된다.
🌳 Hooks를 사용했을 때 얻는 이점
- Functional Component로 통일
- Custom Hooks: 보다 쉬운 상태 로직 재사용
- useEffect: 라이프 사이클 API에 흩어져있던 로직을 묶음
Hooks는 HOC나 render-props 같은 패턴이 가져오는 Component Tree의 불필요한 중첩을 없애줄 수 있고 복잡한 패턴을 적용하지 않고 보다 직관적으로 로직을 재사용할 수 있다.
뿐만 아니라 그간 함수형과 클래스형 두 가지 타입(상태가 있는 경우는 클래스형 컴포넌트로, 뷰만 관리하는 경우는 함수형 컴포넌트로 개발하는 등)을 오가면서 개발했던 것을 함수형 컴포넌트로 통일할 수 있다.
클래스형 컴포넌트에서 componentDidMount와 componentWillUnmount에 흩어져있던 관련 코드도 state 마다 묶을 수 있기 때문에 좀 더 연관성 있는 코드끼리 모을 수 있다.
Reference
Author And Source
이 문제에 관하여(surf react : hooks (useState, useEffect) - 2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@rxjw95/surf-react-hook-useState-useEffect-2저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)