[React 퀵스타트] 6장 - React Hook

David Oh·2023년 2월 3일
0

리액트 훅

6.1 함수 컴포넌트와 리액트 훅

클래스형 컴포넌트는 다양한 생명주기 메서드를 이용할 수 있습니다.

하지만 코드가 간결하지 못하여, 짜임새있는 코드를 작성하기 힘듭니다.

특히, 하나의 생명주기 메서드 내부에 서로 관련이 없는 로직이 함께 작성될 수 있습니다.

그리고 서로 관련이 매우 깊은 코드 역시도 분산되어 작성될 수 있습니다.

  • componentDidMount와 componentWillUnmount
    • 해당 메서드를 이용하는 경우에는 둘은 서로 깊은 연관 관계가 있지만 서로 다른 생명주기 메서드에 작성해야 합니다.
    • 해당 경우가 빈번해지면, 서로 간의 코드에서 일부 기능 구현이 누락되는 경우가 발생합니다.

이러한 이유로 인해 최근에는 함수형 컴포넌트를 사용하며, 클래스형 컴포넌트는 componentDidCactch, getDerivedStateFromProps와 같은 일부 생명주기 메서드의 기능이 필요한 경우에만 제한적으로 사용합니다.

6.2 useState

해당 훅은 함수 컴포넌트에서 상태를 이용하기 위해 사용하는 훅입니다.

//getter
//setter
//StateType
//initialValue

const [getter, setter] = useState<StateType>(initialValue)

6.3 useEffect

해당 훅은 클래스 컴포넌트의 componentDidUpdate, componentDidMount, componentWillUnmount 생명주기 메서드 기능을 제공합니다.

// effectCallBack : 필수로 작성해야 하는 함수, 클린업 함수를 리넡할 수 있습니다.
// depsList : 선택적으로 전달하는 의존 객체 배열 값

useEffect(effectCallback[, depsList])

effectCallback 함수는 해당 훅을 사용할 때 반드시 작성해야 합니다.

  1. 컴포넌트가 마운트 되거나
  2. depsList 배열에 지정한 상태나 속성이 변경되면 호출됩니다.
  • 해당 함수는 클린업 함수를 리턴할 수 있습니다.
  • 클린업 함수는 컴포넌트가 언마운트될 때 실행됩니다.

depsList에 지정된 상태나 속성이 변경되면 effectCallback 함수가 호출됩니다.

하지만 변경되지 않는 경우에는 호출되지 않습니다.

  • []에 내용을 넣어주면 해당 배열이 변할 때만 함수가 호출됩니다.
  • []에 내용을 넣지않고 []만 적어주면 컴포넌트가 마운트 될 때만 실행됩니다.

클린업 함수는 () ⇒ void 형태이며, 컴포넌트가 언마운트될 때 실행됩니다.

useEffect(
	() => {
		// 함수 실행문

		return ( {
		 // 함수 실행문	
		}) 
	}
, [])

useEffect의 장점은 한 컴포넌트 내부에 useEffect 훅을 여러 개 사용할 수 있습니다.

그리고 상태와 상태 관련 로직을 중심으로 해당 훅을 작성할 수 있어서 관련된 코드들이 함께 모여 있게 만들 수 있습니다.

리액트 훅의 생명주기

  • 마운트 시
    • 레이지 초기화
      • 레이지 초기화를 실행합니다.
      • 이는 useState나 useReducer에 전달하는 함수입니다.
        • 이는 비동기로 지연되어 호출됩니다.

          const count = useState<number>(()=> {return 0})

          해당 단계는 컴포넌트가 마운트될 때만 실행됩니다.

          인자로 전달되는 함수 내부에서 실행되는 코드는 마운트 될 때만 실행됩니다.

          상태로 사용할 데이터를 도출하기 위해 복잡한 로직이 필요한 경우에 레이지 초기화가 유용합니다.

    • 렌더링
      • 함수 컴포넌트의 내부 코드가 실행됩니다.
      • 이때, 가상 DOM에 대한 쓰기 작업을 수행합니다.
    • 가상 DOM 업데이트
      • 가상 DOM 트리를 업데이트 합니다.
    • LayoutEffects 실행
      • useLayoutEffect 훅에 지정한 함수를 실행합니다.
    • 브라우저 DOM 업데이트
      • 브라우저 DOM을 업데이트 합니다.
      • 이 단계가 완료되면, 브라우저 화면의 갱신이 완료된 상태가 됩니다.
    • Effects 실행
      • useEffect 훅에 지정한 함수가 호출됩니다.
  • 업데이트 시 : 해당 단계는 부모 컴포넌트가 다시 렌더링 되거나 컴포넌트 자신의 상태 혹은 속성이 변경될 때 일어납니다.
    • 렌더링
    • 가상 DOM 업데이트
    • LayoutEffects 클린업
      • useLayoutEffect 훅의 두번째 인자 전달 여부에 따라 리턴한 클린업 함수가 호출됩니다.
    • LayoutEffects 실행
      • useLayoutEffect 훅의 두번째 인자 전달 여부에 따라 지정한 함수를 실행합니다.
    • 브라우저 DOM 업데이트
    • Effects 클린업
      • useEffect 훅의 두 번째 인자 전달 여부에 따라 리턴한 클린업 함수가 호출됩니다.
      • useEffect 훅의 두 번째 인자 전달 여부에 따라 지정한 함수를 실행합니다.
    • Effects 실행
  • 언마운트 시
    • LayoutEffects 클린업
      • useLayoutEffect 훅이 리턴하는 클린업 함수가 호출됩니다.
    • Effects 클린업
      • useEffect 훅이 리턴하는 클린업 함수가 호출됩니다.

useLayoutEffect 훅이란

useEffect 훅의 콜백 함수는 컴포넌트가 완전히 마운트된 상황 즉 브라우저 DOM에서의 렌더링 작업(paint)이 완료된 후에 실행됩니다.

반면에 useLayoutEffect 훅의 콜백 함수는 컴포넌트가 렌더링되고 브라우저 DOM에서의 렌더링이 실행되기 전에 호출되며 동기적으로만 실행합니다.

복잡하거나 외부 백엔드 API를 읽어오는 과정의 작업은 useEffect 를 사용하고,

간단하면서 렌더링으로 인한 깜빡임을 보여주고 싶지 않은 경웨 사용하면 됩니다.

6.4 useReducer

해당 훅을 이용하면 상태와 관련된 로직을 컴포넌트 밖으로 분리시킬 수 있습니다.

여러 컴포넌트가 유사한 상태 관련 로직이 필요한 경우에 유용합니다.

리듀서의 개념

리듀서는 배열의 메서드 중 reduce 메서드에 인자로 전달되는 함수로부터 유래합니다.

해당 메서드는 배열의 데이터를 이용해 합계를 구할 때 사용할 수 있는 메서드입니다.

//reducer : 리듀서 함수
//initial value : 합계를 구할 때의 초깃값으로 선택적으로 사용할 수 있는 인자

reduce(reducer [, initialValue])

아래와 같은 형태로 사용되며, 리듀서 즉 리듀스에 함수로 전달되는 리듀서 함수의 첫번째 인자는 누적값이 주어지며, 두번째 인자는 각 배열의 한개의 요소가 들어가게 됩니다.

배열.reduce(reducer, initailvalue)

이러한 리듀서 함순슨 순수 함수 입니다.

  • 순수 함수
    • 입력 인자가 동일하면 리턴값도 동일해야 합니다.
      • totalPoint와 member 데이터가 같다면, 리턴되는 값이 동일합니다.
    • 부수 효과가 없어야 합니다.
      • 함수에 전달되는 인자 이외에 외부 리소스에 영향을 주거나 외부 리소스로부터 영향을 받는 부분이 없어야 합니다.
    • 함수에 전달되는 인자는 불변성을 가져야 합니다.
      • 따라서 인자를 변경할 수 없습니다.
      • 함수에 전달되는 인자는 totalPoint, member를 변경하지 ㅇ낳습니다.
      • 새로운 값을 만들어서 리턴해야만 합니다.

Reducer

(state, action) => {
	//state와 action을 이용하여 연산을 수행한 후 새로운 상태를 리턴합니다.
	return newState
} 

useReducer

//state
//dispatch : 상태를 변경하는 메서드
//reducer
//initialState

const [state, dispatch] = useReducer(reducer, initialState)

리듀서의 장점

상태 관리 기능을 컴포넌트로부터 분리할 수 있습니다.

유사한 상태 관리 기능을 사용하는 여러 컴포넌트가 상태 변경과 관리 기능을 공유할 수 있습니다.

불변성을 가지는 상태 변경을 강제하게 되므로, 상태 변경을 추적하기 용이합니다.

어플리케이션 전역 수준의 상태 관리 라이브러리 = redux

6.5 useRef

useState를 통해 상태를 업데이트 하면 컴포넌트가 다시 렌더링 됩니다.

직접 정의한 변수들은 컴포넌트가 다시 렌더링되면 모두 초기화 됩니다.

ref 객체는 컴포넌트의 모든 생명주기 동안에 유지됩니다.

  • 따라서 다시 렌더링되더라도 기존 참조 데이터를 유지합니다.
  • ref 객체가 참조하는 데이터가 변경되더라도 다시 렌더링되지 않습니다.
  • 브라우저 DOM 요소에 직접 접근이 가능합니다.
//initialValue

const refObject = useRef(initialValue)
profile
let David_Oh === UX+Programming

0개의 댓글