리액트 입문기 - Hooks

전클로네·2021년 1월 13일
0

React

목록 보기
10/12

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도 라이브러리로 설치하여 사용을 할 수 있습니다.



참고자료
리액트를 다루는 기술

profile
안녕하세요. 노드로 개발하는 마운틴러버 개발자 입니다.

0개의 댓글