Redux 대신 Context API?

franchesca·2021년 9월 2일
0
post-thumbnail

Context API란?

  • Context API는 Redux와 같은 상태 관리 도구이다.
  • Redux와 다르게 React에서만 사용할 수 있다.
  • Redux와 다르게 여러 저장소가 존재할 수 있다.

Context API는 크게 전역 상태가 저장되는 context, 전역 상태를 제공하는 Provider, 그리고 전역 상태를 받아 사용하는 Consumer로 나뉘어져 있다.

context

  • context는 컴포넌트가 Provide한 상태가 저장된다.
  • Consumer는 이 context를 통해 전역 상태에 접근할 수 있다.
  • 여러 context가 존재할 수 있다. 단, 하나의 context만 존재한다면 성능상 이슈가 있을 수 있으니 유의!

context 안에는 Provider와 Consumer가 정의되어 있으며 다른 컴포넌트에서는 이것들을 이용해 상태에 접근합니다.

import React from 'react'

export default React.createContext({}) // 함수의 인자에는 상태의 초기값이 들어갑니다.

Provider

  • context에 상태를 제공한다.
  • 즉, 다른 컴포넌트가 해당 상태에 접근하여 사용할 수 있다.
  • 제공된 상태에 접근하기 위해서는 Provider의 하위 컴포넌트에 포함되어야 한다.
  • 따라서, 모든 컴포넌트에서 접근해야하는 상태를 제공하기 위해서는 루트 컴포넌트 index.js 혹은 app.js에서 Provider를 정의해야 한다.
import ShopContext from './path/to/shop-context'; // React.createContext() 객체

class App extends Component {
  render() {
    return (
      <ShopContext.Provider value={{
          products: [],
          cart: []
        }
      }>
        {/* 이곳 Provider 사이에 있는 컴포넌트는 전역 상태에 접근할 수 있습니다. */}
      </ShopContext.Provider />
    );
  }
}

consumer

  • consumer는 제공된 상태에 접근하는 방법 중 하나이다.
  • context는 consumer 사이에 있는 처음의 객체를 context에 인자로 전달하기 때문에, 바로 JSX를 작성하는 대신 빈 객체를 작성하고 나서 JSX를 작성해야 한다.
import ShopContext from '../context/shop-context' // React.createContext() 객체

class ProductsPage extends Component {
  render() {
    return (
      <ShopContext.Consumer>  { }
        {context => (
          <React.Fragment>
            <MainNavigation
              cartItemNumber={context.cart.reduce((count, curItem) => {
                return count + curItem.quantity
              }, 0)}
            />
            <main className="products">...</main>
          </React.Fragment>
        )}
      </ShopContext.Consumer>
    )
  }
}

export default ProductsPage

contextType

  • 클래스 컴포넌트에서 static 타입을 이용하여 전역 상태에 접근할 수 있다.
  • Consumer와 다르게 함수형 컴포넌트에서는 사용할 수 없다.
  • 하지만 React Hooks를 이용한다면 함수형 컴포넌트에서도 사용할 순 있습니다.
import ShopContext from '../context/shop-context'

class CartPage extends Component {
  static contextType = ShopContext

  componentDidMount() {
    // 별도의 복잡한 코드 작성 없이 다른 컴포넌트에서 해당 상태에 접근할 수 있습니다.
    console.log(this.context)
  }

  render() {
    return (
      <React.Fragment>
        <MainNavigation
          cartItemNumber={this.context.cart.reduce((count, curItem) => {
            return count + curItem.quantity
          }, 0)}
        />
        <main className="cart">...</main>
      </React.Fragment>
    )
  }
}

export default CartPage

Context API에서는 상태의 갱신을 위해서는 하위 컴포넌트에 Props에 함수를 전달한 것처럼 value를 Provide한 것처럼 상태의 갱신을 위한 함수도 value와 함께 Provide하여 하위 컴포넌트에서 사용해야 한다.

둘의 차이점

Context API

  • 배우기가 쉽다는 장점이 있다.
  • 비교적 적은 양의 코드를 요구하고, 추가로 라이브러리를 사용할 필요가 없기 대문에 번들의 크기를 줄일 수 있다.
    Redux
  • 번들에 라이브러리를 추가해서 사용해야 한다.
  • 사용하기가 비교적 복잡하지만 props drilling 문제를 해결해줄 수 있는 좋은 대안인 건 분명하다.

결론

상태관리 측면에서만 본다면 Context API와 Redux의 성능 차이는 크게 없다. 하지만 Redux는 Context API와 다르게 전역 상태 관리외에 다양한 기능을 제공한다. 따라서 오직 전역의 상태 관리만을 위해 사용한다면 Context API, 그 외의 추가적인 기능을 필요로 한다면 Redux를 사용하면 좋다.

참고: https://academind.com/tutorials/reactjs-redux-vs-context-api/

profile
말하기 보다 생각하는, 생각하기보다 볼 줄 아는 개발자가 되려고 합니다✨

0개의 댓글