데굴데굴

TIL: 2022-11-28 본문

Lesson/TIL

TIL: 2022-11-28

aemaaeng 2022. 11. 28. 16:07

⚙️ 오늘 배운 주제

React Custom Hooks, React Concurrent Feature

🐹 오늘의 기분

오늘도 하루종일 솔로였다. 그래도 저번 주말에는 푹 쉬었어서 컨디션이 나쁘지 않다. usememo, usecallback에 이어서 커스텀 훅을 학습했는데 당최 무슨 소린지 모르겠어서 여러 자료를 찾아보았다. 공식 문서 설명은 너무 어렵게 느껴져서 useFetch나 useInput으로 간단하게 작성된 예제들 먼저 검색해봤는데 이것도 실습에서 겨우 구현해서 더 연습이 필요할 것 같다. 내일은 이 지식을 기반으로 하루종일 과제를 해야 한다. 제대로 찾아보고 내일을 맞이해야겠다.

🗝 키워드

custom hooks, 코드 분할, React.lazy(), React.suspense, fallback

🗣 스스로에게 설명

Custom Hooks

개발자가 스스로 만든 훅
useStateuseEffect처럼 용도대로 커스텀하어 훅을 만들 수 있다.

  • Hook은 보통 디렉토리를 따로 마련하여 그 곳에 작성한다.
  • Hook 함수의 이름은 앞에 use를 붙인다.
  • 리턴하는 값이 조건부여선 안 된다. (불리언으로 리턴하는 것이 적절)
  • Hook 안에 useEffectuseState 같은 기존 React hook을 자유롭게 사용할 수 있다

언제 쓸까?
-> 컴포넌트 내부에서 같은 코드가 반복될 경우

 

기본적으로 input에 입력된 텍스트를 상태로 관리한다면 이런 코드가 쓰이는데
같은 input이 여러 번 쓰여야 하는 상황이라면 이렇게 코드가 반복되는 상황이 생길 것이다

// basic input
import { useState } from 'react';

const App = () => {
  const [text, setText] = useState("");
  const handleChange = (e) => {
    setText(e.target.value);
  }
  return (
    <input value={text} onChange={handleChange}/>
  )
}

// multiple inputs without custom hooks
const App = () => {
  const [text, setText] = useState("");
  const [text2, setText2] = useState("");
  const [text3, setText4] = useState("");
  const handleChange = (e) => {
    setText(e.target.value);
  }
  const handleChange2 = (e) => {
    setText2(e.target.value);
  }
  const handleChange3 = (e) => {
    setText3(e.target.value);
  }
  return (
    <input value={text} onChange={handleChange}/>
    <input value={text2} onChange={handleChange2}/>
    <input value={text3} onChange={handleChange3}/>
  )
}

반복되는 useState 사용과 handleChange 함수를 하나의 Hook으로 묶어버리면 더 깔끔한 코드 작성이 가능해진다.

// useInput.js
import { useState } from 'react';

const useInput = (initialValue) => {
  const [value, setValue] = useState(initialValue);
  const handleChange = (e) => {
    setValue(e.target.value);
  }
  return [value, handleChange];
}

export default useInput
// multiple inputs with custom hooks
import useInput from './Hooks';

const App = () => {
  const [text, setText] = useInput("");
  const [text2, setText2] = useInput("");
  const [text3, setText4] = useInput("");

  return (
    <input value={text} onChange={setText}/>
    <input value={text2} onChange={setText2}/>
    <input value={text3} onChange={setText3}/>
  )
}

input 말고도 fetch와 같이 다양한 상황에 필요가 느껴진다면 자유롭게 사용할 수 있다.

 

custom hook은 솔직히 글로만은 전혀 이해가 안 돼서 영상을 몇 개 찾아봤다.
아래는 이해하는데 도움이 됐던 영상들이다.

 

React concurrent features

코드 분할

모던 웹으로 발전하면서 DOM을 다루는 정도가 정교해지면서 자바스크립트 코드 또한 무거워짐.
-> 번들링 후 코드 실행 시간 증가

 

idea: 번들을 나눈 뒤 필요한 코드만 불러오면 어떨까?
어디서 느려졌는지 파악한 후 그 부분은 냅두고 지금 필요한 부분만 불러오자

 

번들을 물리적으로 나눈다
런타임 시 여러 번들을 동적으로 만들고 불러오는 것. 번들러에서 지원한다.

-> 대규모 프로젝트에서도 로딩 속도 개선 가능

 

서드파티 라이브러리를 불러올 때 딱 필요한 부분만 불러오는 것만 해줘도 코드의 경량화에 도움된다.

// No
import _ from 'lodash';

// Yes
import find from 'lodash/find';

첫 코드는 lodash 라이브러리 전체에서 언더바를 불러오고 있다.
만약 언더바의 용도가 오로지 find만을 쓰기 위함이라면 아래 코드처럼 불러오는 것이 더 적절하다.

 

리액트는 SPA.
사용하지 않는 모든 컴포넌트들까지 한 번에 불러와 첫 화면 렌더링이 오래걸림.

 

React에서의 코드 분할은 Dynamic import로 할 수 있다.
static import: 파일의 최상위에서 import 지시자로 라이브러리 및 파일을 불러오는 방식

Dynamic import로 아래처럼 불러올 수 있다.
이러면 이 모듈이 필요없는 곳에서는 불러와지지 않게 된다.

import('somelibrary.somemodule')
  .then(module => module.default)
  .then(someFunction())
  .catch(handleError());
React.lazy()

dymanic import를 사용해 컴포넌트 렌더링이 가능

// Component 폴더에서 Component라는 이름으로 Component를 불러온다
const Component = React.lazy(() => import('./Component'));

React.lazy()는 단독으로는 쓰일 수 없고, React.suspense 컴포넌트의 하위에서 렌더링해야 한다.

React.Suspense

React.lazy로 import하게 되면 로딩하는 시간이 생기게 됨
아직 렌더링이 준비되지 않은 컴포넌트가 있을 때 로딩 화면을 보여주고 로딩이 완료되면 렌더링이 준비된 컴포넌트를 보여준다.
React.Suspense는 App.js에서 라우터를 적용시키며 같이 적용하는 것이 간단하다.
(라우터가 분기되는 컴포넌트에서 각 컴포넌트에 React.lazy를 사용하여 import하는 방식)
초기 렌더링 시간이 줄어든다는 장점 but 이동과정마다 로딩 화면이 보여지기 때문에 적용 여부를 잘 결정해야 함.

❓ 막혔던 부분

custom hook의 로직을 짜는 것과 이를 컴포넌트에 불러와 적용하는 방식이 이해되지 않았었다.
영상을 몇 개 찾아본 결과 약간 갈피는 잡힌 듯하지만 더 다양한 예제를 볼 필요가 있다.

'Lesson > TIL' 카테고리의 다른 글

TIL: 2022-11-30  (0) 2022.11.30
TIL: 2022-11-29  (0) 2022.11.29
TIL: 2022-11-25  (0) 2022.11.25
TIL: 2022-11-24  (0) 2022.11.24
TIL: 2022-11-23  (0) 2022.11.23
Comments