props 지옥을 해결하자 / useContext

support·2022년 3월 13일
1

Today I Learned

목록 보기
2/11
post-thumbnail

첫 프로젝트에서 상태관리라이브러리를 사용하지 않고 시작한 탓에
거의 모든 페이지에 props 지옥으로 로그인과 유저정보를 넘겨줘야 했다

파이널 프로젝트 전에 props 지옥을 해결할 방안을 공부해보자

props 지옥은 useContext를 사용해서 해결할 수도 있고
redux, mobx, recoil, zustand 등등 상태관리 라이브러리들 중에서 골라서 사용하면 해결할 수 있다

라이브러리 중에서는 redux가 대부분의 프론트엔드의 상태관리 기술 스택으로 사용되고 있어서 redux로 정했다

useContext가 좋을까 redux가 좋을까?
단순히 글로벌상태를 사용하려 한다면 useContext를 사용해도 괜찮다
리덕스와의 차이는 성능에서 나타나게 되는데 리덕스에서는 글로벌 상태의 값을 가져와서 사용하게 된다면 해당 값이 바뀔 때만 리랜더링이 되도록 최적화가 되어있지만 context에는 성능 최적화가 되어있지 않다
컴포넌트에서 Context의 특정 값을 의존하는 경우, 해당 값 말고 다른 값이 변경 될 때에도 컴포넌트에서는 리렌더링이 발생하게 되고
Context를 사용한다면 불필요한 리랜더링을 줄이기 위해 Context를 분리하는 과정이 필요하다
그렇기 때문에 글로벌 상태가 많아진다면 리덕스를 사용하는 것이 더 좋을 것 같다


useContext란?

Context에 대해서 먼저 알아야 한다

공식 홈페이지에서는 context를 아래처럼 정의하고 있다
context를 이용하면 단계마다 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있습니다.

일반적인 React 애플리케이션에서 데이터는 부모로부터 자식에게 props를 통해 전달되지만, 애플리케이션 안의 여러 컴포넌트들에 전해줘야 하는 props의 경우 context를 이용하면, 중간 컴포넌트 들에게 명시적으로 props를 넘겨주지 않아도 많은 컴포넌트가 이러한 값을 공유하도록 할 수 있다.

1. context를 사용하기 전에 고려할 것

context를 사용하면 컴포넌트를 재사용하기가 어려워지기 때문에 꼭 필요할 때만 사용해야 하고, 어떨때는 context보다 컴포넌트를 합치는게 더 효율적일 때가 있다

2. context 사용법

context API를 사용해보자!
createContext, Provider , Consumer 에 대해서 알아야 한다

createContext : context 객체를 만든다
Provider : 하위 컴포넌트들에게 context의 변화를 알린다
Consumer : context의 변화를 감지하는 컴포넌트이다

app.js

import React, { useState, createContext } from "react";

import "./styles.css";
import Children from "./Children";

// MyContext 생성
export const MyContext = createContext();

export default function App() {
  const [user, setUser] = useState({
    username: "망고",
    userage: "5살"
  });
  return (
    <MyContext.Provider value={user}>
      <Children />
    </MyContext.Provider>
  );
}

Consumer 사용

Children.js

import React from "react";
import { MyContext } from "./App";

function Children() {
  return (
    <MyContext.Consumer>
      {(user) => (
        <div>
          <div>MyContext로 불러온 username은 {user.username}</div>
          <div>MyContext로 불러온 age는 {user.userage} </div>
        </div>
      )}
    </MyContext.Consumer>
  );
}

export default Children;

useContext 사용

Children.js

import React, { useContext } from "react";
import { MyContext } from "./App";

function Children() {
  const user = useContext(MyContext);

  return (
    <div>
      <div>MyContext로 불러온 username은 {user.username}</div>
      <div>MyContext로 불러온 age는 {user.userage} </div>
    </div>
  );
}

export default Children;

useContext 함수를 사용하면 App.js 에서 Context 생성 후
Children.js에서 MyContext 사용시 Consumer를 사용하지 않고도
const user = useContext(MyContext);
한줄의 코드로 사용이 가능하다
CodeSandbox

0개의 댓글