본문 바로가기
React

Hooks

by spare8433 2022. 2. 22.

Hook 을 제대로 알지 못하고 리액트 개발을 시작하는 것은 니퍼를 들고 나사못을 빼는 헛짓거리 일거 같아 확실히 정리하기 위해 적어두려함

Hook 이 무엇이냐?


기존 Reactclass 바탕의 복잡한 코드를 작성할 필요 없이 여러 React 기능을 functional component 에서 쉽게 사용 할 수 있게 해주는 것이 Hook 인 것이다.



중요한 부분은 functional component 에서 state 를 가질 수 있게 된 것과 기존의 React 에서는 class component, render(복잡한 라이프 사이클과 그에 대응하는 메서드들 ..) 이런 귀찮은 짓을 안하고 하나의 function 에서 모든 것을 할 수 있게 된 점 정도로 정리할 수 있을 것 같다.

중요 Hook


비구조화 할당 (구조분해)

들어가기 앞서 알아둘 문법이 있다.


// 일반적인 스타일
const array = [1, 2];    
const one = array[0];
const two = array[1];

// 배열 비구조화 할당
const array = [1, 2]
const [one, two] =array;

  • 상단의 코드처럼 하단의 코드도 배열의 순서에 맞게 대칭 되는 값을 할당해주는 코드이다.
  • 객체에서도 동일한 방식으로 활용 할 수 있다.

useState

state 와 변경해주는 함수 선언하여 상태 관리할 때 사용하는 Hook


// state 선언 
const [value, setValue] = useState(0)

useEffect

컴포넌트가 렌더링 될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hook


// 마운트 될때(처음 DOM 이 생성되었을때) 만 실행됨
useEffect(() => {console.log('처음 마운트 될 때 실행됩니다.')},[])

// 특정값이 업데이트 될때만 실행됨
useEffect(() => {console.log('특정 값이 업데이트 될 때 실행됩니다.')} ,[value])

// 컴포넌트가 언마운트 되기 전이나 업데이트 직전에 어떠한 작업을 수행하고 싶을때 cleanup 함수를 반환해서 사용함
useEffect(() => {
  console.log('특정 값이 업데이트 될 때 실행됩니다.')
  return() => {console.log('컴포넌트가 언마운트 되기 전이나 업데이트 직전에 실행됨')}
} ,[value])

useReducer

useState 보다 더 다양한 상황에서 state 값을 업데이트해 주고 싶을 때 사용

리듀서는 현재상태 , 업데이트를 위한 정보를 담은 액션(action) 값을 전달받아 새로운 상태를 반환하는 함수이다

리듀서 함수에서 새로운 상태를 만들 때에는 불변성을 지켜주어야 한다.


불변성의 중요성 : https://spare8433.tistory.com/2


const reducer = (state,action) => {
    switch (action.type){
        case 'INCREMENT':
            return{value : state.value + 1}        // {...state,value : state.value + 1}
        default:
            return state
    }
}
export const Counter = () => {
    const [state, dispatch] = useReducer(reducer, {value:0} )
    return(
        <div>
            <button  onClick={()=>  dispatch({type:'INCREMENT'})}>버튼</button>
            <div>{state.value}</div>
        </div>
    )
}

  • useState 처럼 state 를 업데이트해주는 함수( reducer ) 를 따로 만들어 쓴다고 생각하면 됨
  • 지정한 함수 dispatch 에 액션 객체를 던져주면 액션 값을 토대로 리듀서 함수가 state 상태를 변화시킴

useMemo

랜더링시에 원하는 값이 바뀌지 않았다면 이전에 저장해두었던 결과를 다시사용하는 방식(memoization)

memoization : 기존에 수행한 연산의 결과값을 어딘가에 저장해두고
동일한 입력이 들어오면 재활용하는 프로그래밍 기법


import {React, useState, useMemo} from  'react'

const  Test  = () => {
    const [list, setList] =  useState([])
    const [number, setNumber] =  useState('')

    const  onChange  = (e) => {
        setNumber(e.target.value)
        console.log('number state 변경됨');
    }

    const  oninsert  = () => {
        setList([...list,parseInt(number)])
    }

    const  getAvg  = () => {
        let  result  =0;
        list.map(vlaue  =>  result  +=  vlaue)
        console.log('getAvg 실행')
        return  result  /  list.length
    }

    const  avg  =  useMemo(getAvg,[list])

    return (
        <div>
            <input  type='text'  onChange={onChange}></input>
            <button  onClick={oninsert}>버튼</button>

            <ul> {list.map(value  => { return  <li>{value}</li> })} </ul>
            <div>{avg}</div>
        </div>
    )
}

export  default  Test

코드 설명

  • 입력 창에 값을 적을 때마다 onChange 함수가 호출 number 값이 변화되어 리렌더링 됨
  • 버튼 클릭 시 입력 창 데이터가 list 에 저장 됨
  • list 가 변경 getAvg가 호출되어 avg 값이 저장됨
  • 입력 창에 값을 적을 때마다 리렌더링 되지만 useMemo 로 설정된 avg 값은 list 의 값이 전 과 동일 하지 않을 때만 getAvg가 호출 되어 변화하게 된다.

+ 값이 업데이트 되더라도 동일한 값이라면 실행하지 않게 되는 것이다.

useCallback

useMemo 처럼 함수를 재활용 해야 할 시에 사용하고, 주로 랜더링 성능을 최적화 해야 하는 상황에서 사용됨

리랜더링 될 때마다 코드가 긴 함수를 정의한다면 효율적이지 못할 것이다.

const onChange = useCallback((e) => { 
    setNumber(e.target.value); 
    console.log('number state 변경됨'); 
},[]) // 컴포넌트가 처음 리랜더링될 때 마다 함수 생성

const oninsert  = useCallback(() => {
        setList([...list,parseInt(number)])
},[list, number]) // list, number 의 값이 변경 될 때 마다 함수 생성

  • useMemo 코드 중 일부 함수를 useCallback 으로 선언한 코드
  • 기억하자 useCallbackuseMemo 함수 버전이다.

useMemo, useCallback의 주의점

useMemo, useCallback의 과도한 사용은 성능 향상의 이점보다는 유지보수를 어렵게 할 수 있으므로 성능 최적화가 필요한 부분에만 쓰는 것을 권장한다.


최적화가 필요할 정도의 크고 비중 있는 부분만 쓰는 게 정설 인 듯 하다.

관련 내용 링크: https://uzihoon.com/post/ef453fd0-ab14-11ea-98ac-61734eebc216

useRef

  • ref 가 무엇인지 감이 잘 안온다면 참고

ref 를 알아보자 (ref DOM) : https://spare8433.tistory.com/5

import {React, useRef} from  'react'

const Test = () => {
    const input = useRef();

    const onClick = () => {
    alert(input.current.value)
    }
    return (
        <div>
            <input type='text' ref={input}></input>
            <button onClick={onClick}>버튼</button>
        </div>
    )
}
export  default Test

  • ref 설정 간단하게하는 훅

커스텀 훅

  • 추후 직접 써보고 업데이트 예정

부족한 부분은 지속적으로 업데이트 될 예정 (많이 써봐야 될 것 같은 부분 인지라)