리액트 입문기 - Hooks
Hooks는 리액트 v16.3에 새로 도입된 기능으로 함수형 컴포넌트에서도 상태 관리를 할 수 있습니다.
지금 부터 Hook에 대해 알아보도록 하겠습니다.
useState
useState는 가장 기본적인 Hook이며, 함수형 컴포넌트에서도 가변적인 상태를 지닐 수 있게 해줍니다.
* useState예제
import React, { useState } from 'react'; const Counter = () => { const [ value, setValue ] = useState(0); return ( <div> <p> 현재 카운터 값은 <b>{value}</b>입니다. </p> <button onClick={() => {setValue(value + 1)}} >+1</button> <button onClick={() => {setValue(value - 1)}} >-1</button> </div> ); } export default Counter;
useEffect
useEffect는 리액트 컴포넌트가 렌더링 될때마다 특정 작업을 수행하도록 설정 할 수 있는 Hook입니다.
클래스형 컴포넌트의 componentDidMount와 compoenetDidUpdate를 합친 형태로 볼 수 있습니다.
* useEffect예제
useEffect(() => { console.log('렌더링이 완료되었습니다.'); console.log({ name, nicName }); });
useEffect가 화면에 처음 랜더링 될때만 실행하고, 업데이트때는 실행하지 않으려면 함수의 두번째 파라미터로 비어있는 배열을 넣어주면 됩니다.
* 마운트 될때만 사용하고 싶을때
useEffect(() => { console.log('마운트 될때만 실행합니다.'); }, [ ]);
컴포넌트가 언마운트 되기 전이나 업데이트되기 직전에 어떠한 작업을 수행하고 싶다면 뒷정리(cleanup)함수를 반환해주어야 합니다.
* cleaup 사용예시
useEffect(() => { console.log('effect'); console.log(name); return () => { console.log('cleanup'); console.log(name); }; });
useReducer
useState보다 더 다양한 컴포넌트의 상황에 따라 다양한 상태를 다른 값으로 업데이트해 주고 싶을때 사용하는 Hook입니다.
reducer는 현재 상태, 업데이트를 위해 필요한 정보를 담은 액션값을 전달받아 새로운 상태로 반환하는 함수입니다.
* useReducer예제
import React, { useReducer } from 'react'; function reducer(state, action){ switch (action.type) { case 'INCREMENT': return {value: state.value + 1}; case 'DECREMENT': return {value: state.value - 1}; default: return state; } } const CounterReducer = () => { const [ state, dispatch ] = useReducer(reducer, { value: 0 }); return ( <div> <p> 현재 카운터의 값은 <b>{state.value}</b> 입니다. </p> <button onClick={() => dispatch({type:'INCREMENT'})} >+1</button> <button onClick={() => dispatch({type:'DECREMENT'})} >-1</button> </div> ); } export default CounterReducer;
useReducer의 첫번째 파라미터는 리듀서 함수를 넣고, 두번째 파라미터에는 함수의 기본값을 넣어줍니다.
이 Hook을 사용하면 state값과 dispatch함수를 받아오게 되고 함수 안에 파라미터로 액션 값을 넣어주면 리듀서 함수가 호출되는 구조입니다.
useReducer를 사용하면 컴포넌트 업데이트 로직을 컴포넌트 바깥으로 빼낼 수 있다는 장점이 있습니다.
useMemo
useMemo를 사용하면 함수형 컴포넌트 내부에서 발생하는 연산을 최적화 할 수 있습니다.
* useMemo예제
import React, { useState, useMemo } from 'react'; const getAverage = (numbers) => { console.log('평균 값 계산 중..'); if (numbers.length === 0) return 0; const sum = numbers.reduce((a,b) => a+b); //reduce : 값을 누적시키는 함수 return sum / numbers.length; }; const Average = () => { const [ number, setNumber ] = useState(''); const [ list, setList ] = useState([ ]); const onchangeNumber = (e) => { setNumber(e.target.value); }; const onInsert = (e) => { const nextList = list.concat(parseInt(number)); setList(nextList); setNumber(''); }; const avg = useMemo(() => getAverage(list), [ list ]); return ( <div> <input value={number} onChange={onchangeNumber}></input> <button onClick={onInsert}>등록</button> <ul> {list.map((value, index) => (<li key={index}>{value}</li>))} </ul> <div> <b>평균값: </b>{avg} </div> </div> ); }; export default Average;
useMemo를 사용하여 등록버튼을 클릭할때만 getAverage를 호출할 수 있습니다.
useCallback
useCallback은 useMemo와 상당히 비슷합니다. 주로 렌더링 성능을 최적화해야하는 상황에서 사용합니다.
이 Hook을 사용하면 이벤트 핸들러 함수를 필요한 때만 생성 할 수 있습니다.
* useCallback예제
const onInsert = useCallback(() => { const nextList = list.concat(parseInt(number)); setList(nextList); setNumber(''); },[ number, list ]);
첫번째 파라미터에는 생성하고 싶은 함수를 넣고, 두번째 파라미터에는 배열을 넣으면 됩니다.
숫자,문자열,객체처럼 일반 값을 재사용하려면 useMemo
함수를 재사용하려면 useCallback을 사용하면 됩니다.
useRef
함수형 컴포넌트에서 ref를 쉽게 사용할 수 있도록 해주는 Hook입니다.
* useRef예제
const inputEL = userRef(null); const onInsert = useCallback(() => { const nextList = list.concat(parseInt(number)); setList(nextList); setNumber(''); inputEL.current.focus(); },[ number, list ]);
추가로 로컬변수를 사용해야 할 때도 useRef를 활용할 수 있습니다.
로컬변수란?
렌더링과 상관없이 바뀔 수 있는 값
커스텀 Hooks만들기
여러컴포넌트에서 비슷한 기능을 공유할 경우, 이를 Hook으로 작성하여 로직을 재사용할 수 있습니다.
다른 개발자가 만든 Hook도 라이브러리로 설치하여 사용을 할 수 있습니다.
참고자료
리액트를 다루는 기술
Author And Source
이 문제에 관하여(리액트 입문기 - Hooks), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@rkgus3575/리액트-입문기-Hooks저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)