2023-03-20 월요일

·2023년 3월 20일
0

Today I Learned

목록 보기
87/114
post-thumbnail

✏️ 무엇을 배웠나


1. useContext

useContext란

리액트에서 Props Drilling을 해결할 수 있는 방법 중 하나다. useContext를 사용해 어떤 자식 컴포넌트일지라도 부모 컴포넌트에 있는 데이터를 사용할 수 있다.

사용하는 방법
1. context를 만든다
2. useContext를 이용해 context를 사용한다
3. context provider로 자식 컴포넌트를 감싸준다
언제 context를 사용해야 하나
  1. Props 전달로 해결되지 않는 경우
  2. 컴포넌트를 추출해 JSX를 children으로 내려줘도 해결되지 않는 경우 ( 이렇게 하면 무의미한 Props Drilling을 최소화할 수 있음)

이 2가지 해법이 적절하지 않는 상황에서 context 사용을 고려할 수 있다. 컴포넌트 트리 최상단에서 아주 멀리 떨어진 일부 컴포넌트에서 특정 데이터가 필요할 때 context가 도움이 될 수 있다.

사용 예시
  • 현재 로그인한 계정
  • 테마
  • 라우팅
  • 상태 관리
props 대신 context를 사용하는 예시

Before : imageSize가 props로 계속 전달되고 있는 상황

// App.js
import { useState } from 'react';
import { places } from './data.js';
import { getImageUrl } from './utils.js';

export default function App() {
  const [isLarge, setIsLarge] = useState(false);
  const imageSize = isLarge ? 150 : 100;
  return (
    <>
      <label>
        <input
          type="checkbox"
          checked={isLarge}
          onChange={e => {
            setIsLarge(e.target.checked);
          }}
        />
        Use large images
      </label>
      <hr />
      <List imageSize={imageSize} />
    </>
  )
}

function List({ imageSize }) {
  const listItems = places.map(place =>
    <li key={place.id}>
      <Place
        place={place}
        imageSize={imageSize}
      />
    </li>
  );
  return <ul>{listItems}</ul>;
}

function Place({ place, imageSize }) {
  return (
    <>
      <PlaceImage
        place={place}
        imageSize={imageSize}
      />
      <p>
        <b>{place.name}</b>
        {': ' + place.description}
      </p>
    </>
  );
}

function PlaceImage({ place, imageSize }) {
  return (
    <img
      src={getImageUrl(place)}
      alt={place.name}
      width={imageSize}
      height={imageSize}
    />
  );
}

After : context를 이용해 props 제거

1) imageSize props를 대체할 context 생성

// Context.js
import { createContext } from "react";
export const ImageSizeContext = createContext();

2) 프로바이더로 list를 감싸준 뒤, PlaceImage 컴포넌트에서 useContext를 사용해 context 사용하고 기존 props 제거

// App.js
import { useState, useContext } from "react";
import { places } from "./data.js";
import { getImageUrl } from "./utils.js";
import { ImageSizeContext } from "./Context.js";

export default function App() {
  const [isLarge, setIsLarge] = useState(false);
  const imageSize = isLarge ? 150 : 100;
  return (
    <ImageSizeContext.Provider value={imageSize}>
      <label>
        <input
          type="checkbox"
          checked={isLarge}
          onChange={(e) => {
            setIsLarge(e.target.checked);
          }}
        />
        Use large images
      </label>
      <hr />
      <List />
    </ImageSizeContext.Provider>
  );
}

function List() {
  const listItems = places.map((place) => (
    <li key={place.id}>
      <Place place={place} />
    </li>
  ));
  return <ul>{listItems}</ul>;
}

function Place({ place }) {
  return (
    <>
      <PlaceImage place={place} />
      <p>
        <b>{place.name}</b>
        {": " + place.description}
      </p>
    </>
  );
}

function PlaceImage({ place }) {
  const imageSize  = useContext(ImageSizeContext);
  return (
    <img
      src={getImageUrl(place)}
      alt={place.name}
      width={imageSize}
      height={imageSize}
    />
  );
}
  • 위 코드는 react.dev에서 제공하는 퀴즈에서 가져왔습니다.

🏷️ 오늘의 코멘트

useContext로 유저 로그인 추적을 할 수 있구나! 이전 프로젝트에서는 전역 상태로 추적했었는데, 기회가 되면 다음에 써봐야겠다.

profile
⛰ 프론트엔드 개발 공부 블로그

0개의 댓글