[TIL] 22.05.10

kyh·2022년 5월 10일

원티드 프리온보딩

목록 보기
5/12

Recoil

React의 상태 관리를 할 수 있는 라이브러리 중 하나로, 과제로 인해 처음 사용하게 됐는데 공식 문서에 설명이 그렇게 복잡하지는 않아서 관련 자습서 내용을 따라 진행해봤다.

주요 개념

1. RecoilRoot : Recoil을 사용하기 위해서는 루트 컴포넌트에 다음과 같이 이 RecodilRoot라는 컴포넌트를 감싸주어 전역에서 상태를 관리할 수 있도록 해주어야한다.

import React from "react";
import ReactDOM from "react-dom/client";
import { RecoilRoot } from "recoil";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <RecoilRoot>
      <App />
    </RecoilRoot>
  </React.StrictMode>
);

2. atom: Recoil에서는 상태 단위 값으로 atoms을 사용한다. 마치 Hooks에서 사용하는 useState와 비슷하지만 전역에서 사용할 수 있다는 부분이 다르다.

< src/state/text.js >

import { atom } from "recoil";

export default atom({
  key: "TextState",
  default: "",
});
  • atom({ key, default })
    • key : 여기서 사용하는 키 값은 문자열로 프로젝트 전체에서 사용하는 다른 atom들과 구별되는 고유한 이름(문자열)으로 작성해야한다.
    • default : 초기 값을 설정하는 곳으로 프로젝트 내 어딘가에 어떤 atom 값이 변경되면, 참조하고 있는 이 값에 업데이트가 일어난다.

< src/state/index.js >

import TextState from "./text";
import CharCountState from "./charCount";

export { TextState, CharCountState };
  • 많은 atom을 관리하기 위해 보통 state라는 폴더를 두고 atom을 만들어서 export default 한 후 그 atom을 index.js에 모아서 한 번에 보기 좋게 관리하는 형식을 많이 이용한다. (state 디렉토리 안의 index.js 라는 것에 유의한다.)

< src/components/TodoList.jsx >

import React from "react";
import { useRecoilState } from "recoil";
import { TextState } from "../state";

function TodoList() {
  const [text, setText] = useRecoilState(TextState);

  const onChange = (e) => {
    setText(e.currentTarget.value);
  };

  return (
    <div>
      <input type="text" value={text} onChange={onChange} />
      <br />
      Echo : {text}
    </div>
  );
}

export default TodoList;
  • 2.1 useRecoilState : 위에서 설정한 "TextState"라는 key 값의 atom을 사용하기 위해서는 이와 같이 useState를 import 하는 것처럼 recoil에서는 useRecoilState를 사용한다. 사용하는 방법은 setState로 상태를 업데이트하고, state로 값을 읽기 때문에 Hooks의 useState 처럼 사용한다.

3. selector : 비동기 처리 혹은 복잡한 로직을 처리하기 위해서 사용하는 특정 atom의 파생된 상태로 크게 두 가지 기능을 가지고 있다.

  • atom의 값을 구독하고 있다가 이 값이 업데이트 되면 selector 내부의 함수가 실행
  • 서버와 통신 이후 (비동기) , response의 data를 자신의 값으로 가짐

< src/state/charCount >

import { selector } from "recoil";
import textState from "../state/text";

export default selector({
  key: "charCountState",
  get: ({ get }) => {
    const text = get(textState);
    return text.length;
  },
});
  • get 속성에 textState라는 atom을 받아 변경될 때마다 atom의 길이를 반환하는 selector로 set은 옵션으로 사용하지 않는다면 위처럼 읽기 전용으로 사용되며, 함수를 반환하는 역할만 수행한다.
  • selector({ key, get, [ set ] })

    get 속성만 사용하는 경우 읽기 전용이고, set까지 사용하는 경우 양방향으로 쓰기가 가능해진다.

    • key: atom의 key와 마찬가지로 프로젝트 전체에서 고유한 이름(문자열)을 가져야 한다.
    • get : 함수가 할당될 수 있는 속성으로 atom의 값을 구독(인자로 가지고)하고 있다가, 그 값이 업데이트되면 그 내부의 함수가 재실행하게 된다.
    • set : 수정 가능한 state 값을 변경할 수 있는 함수를 반환하는 속성으로 자기 자신의 값이 아닌 다른 atom에 대한 값을 수정할 수 있다.

< src/components/CharCount.jsx >

import React from "react";
import { useRecoilValue } from "recoil";
import { CharCountState } from "./state";

function CharCount() {
  const counter = useRecoilValue(CharCountState);
  return <div>Character Count : {counter}</div>;
}

export default CharCount;
  • 3.1 useRecoilValue : 구독하는 값만 반환하는 함수로 값에 set을 안쓰는 경우 사용한다.
  • 3.2 useSetRecoilState : 구독하는 값을 변경하는 함수만 반환한다.

코드리뷰 내용

당부하고 싶은 말

  • 린터와 프리티어를 절대 끄지 말 것
  • 에러, 워닝 뜨지 않도록 하기

디렉터리 구조 및 작명법

  • 비슷한 성질의 컴포넌트끼리 모아놓는 것이 좋다.
  • module.scss > 클래스명으로 들어오기 때문에 camel case로 작성하자

React Router - Layout

  • React Router 6 기준, Layout 기능은 페이지마다 공통적인 부분을 정의할 수 있게 해준다. 즉 Layout을 만들어두면 그 안의 Outlet의 라우팅에 따른 컴포넌트를 넣을 수 있다는 의미
  • Nav : 브라우저의 주소를 설정된 곳으로 바꿔주며, 실제 페이지를 불러오지는 않는다.
  • NavLink : Link + CSS, 특정 링크에 스타일을 넣어주는 기능이 추가된 Link로 내부에 클래스명을 주고, 해당 링크가 클릭되면 클래스명의 불린 값이 들어오면서 스타일이 적용되는 식이다.

.env.copy

.env 파일은 gitIngore로 인해 리모트 저장소에 등록되지 않는다. API Key를 이곳에 두고 호출해서 변수명으로 가져와 사용함으로써 키가 유출되는 것을 막을 수 있다. 이를 이용해서 복사본을 만들어두면 추후 사용자가 API Key를 소유자에게 요청할 수 있게끔 할 수 있다. ( 작업 용이성 증가 ?)

Throttling / Debouncing

  • Throttling : 마지막 함수가 호출된 일정 시간이 지나기 전에 다시 호출되지 않도록 하는 것으로 주 사용처는 스크롤 조작을 할 때 사용한다. (실행 횟수를 제한함으로써 성능 문제에 대한 처리를 위해)
  • Debouncing : 연속해서 호출되는 함수들 중 마지막 함수 ( 혹은 제일 처음 )만 호출하도록 하는 것으로 주 사용처는 ajax 와 같은 비동기 통신에서 검색하는 기능을 구현할 때 자주 사용한다.

TypeScript

  • any 압수
  • 기존 레거시에서 ts로 전환할 때, 무엇이 들어올지 모르는 복잡한 코드에 대해 any 타입으로 두고 리팩토링 진행할 때 쓴다고 한다.

Axios

  • URL은 services에 Axios 인스턴스를 만들어 놓고 쓰자.

0개의 댓글