본문 바로가기

Computer Programming/[리액트를 다루는 기술]

[리액트를 다루는 기술] 15. Context API 연습 w/ Vite

1. 프로젝트 생성  - Vite

지금까지는 CRA를 사용하여 리액트 프로젝트를 만들었었는데, 간단한 프로젝트에는 Vite 또한 많이 사용하고 있고 실제로 더 빠른 개발 서버를 시작시킬 수 있고 확장성이 좋다고 하여 이번 연습 프로젝트를 Vite로 구성했다.

 

Vite란 Vue.js 프레임워크 제작자인 Evan You가 만든 빌드 도구로, 빠르고 간결한 모던 웹 프로젝트 개발 경험에 초점을 맞춰 탄생했다. Webpack을 기반으로 한 CRA와 다르게 ES모듈을 기반으로 하여 다양한 기능을 제공하며 무엇보다 빠르다....!

 

CRA는 불필요한 모듈도 전체 번들링을 하지만, Vite는 개별 파일이 모듈로 로드되고 캐싱되어서 초기 로딩 속도를 향상시킨다.

 

 

사용방법은 여기에!

https://vitejs.dev/guide/

 

Vite

Next Generation Frontend Tooling

vitejs.dev

 

 

 

2. Context API - Consumer, Provider 사용하기

import { createContext } from "react";

const ColorContext = createContext({color: 'black'})

export default ColorContext

초깃값 value 을 createContext의 파라미터로 전달한다. 이 부분이 안 되어 있으면 나중에 Provider을 사용할 때 초깃값이 없어 오류가 생긴다. context를 만들었으면 이제 이 정적인 값인 {color: black}을 조회하는 컴포넌트를 만들어서 잘 연결되는지 확인해보면 된다. 

 

 

Color를 조회하는 ColorBox에서 context consumer을 통해 조회해보자

const ColorBox = () => {
    return (
            <ColorContext.Consumer>
                {value => (
                    <div style={{height: "64px", width: "64px", backgroundColor: value.color}} />
                )}
            </ColorContext.Consumer>
        )
}

 

그리고 Provider을 사용하면 value 값을 변경할 수 있다.

ColorBox를 렌더하고 있는 App.js에서 Provider를 사용하면 된다.

//App.js
return (
    <ColorContext.Provider value={{ color : 'red' }}>
      <div>
        <ColorBox />
      </div>
    </ColorContext.Provider>
)

 

 

 

 

3. 동적 Context 사용하기

context API는 정적인 2번 내용보다는 함수를 전달해주거나 동적으로 데이터를 바꾸는 경우 더 자주 사용된다.

 

컨텍스트 파일을 수정할건데 다른 컴포넌트에서 Provider와 Consumer 을 사용할 수 있도록 이 두 가지를 export 해준다.

그리고 state 뿐만 아니라 action key를 통해 함수를 전달해준다.

 

또한 Context creator의 초깃값과 provider의 value 의 형태를 통일시켜주는것이 가독성이나 유지보수에 좋다. 

// context/color.js
import { createContext, useState } from "react";

const ColorContext = createContext({
    state: {color: 'black', subColor: 'red'},
    action: {
        setColor: () => {},
        setSubColor: () => {},
    }
})

// eslint-disable-next-line react/prop-types
const ColorProvider = ({ children }) => {
    const [ color, setColor ] = useState('black')
    const [ subColor, setSubColor] = useState('red')

    const value = {
        state: {color, subColor},
        actions: {setColor, setSubColor}
    }

    return (
        <ColorContext.Provider value={value}>
            {children}
        </ColorContext.Provider>
    )
}

const { Consumer : ColorConsumer } = ColorContext;

export { ColorProvider, ColorConsumer } ;

 

이 데이터를 사용하고 있는 컴포넌트에서도 value값을 사용할 때 value.state.color 또는 value.action.setColor 등으로 접근해서 사용하면 편리하다.

 

 

그리고나서 이제 원래 정적 데이터를 불러오던 Consumer도 수정해주고, 

 

<ColorConsumer>
    {value => (
        <div style={{height: "64px", width: "64px", backgroundColor: value.state.subColor}} />
    )}
</ColorConsumer>

 

비구조화 할당을 통해 아래와 같이 바꿔도 된다.

<ColorConsumer>
    {({ state }) => (
        <div style={{height: "64px", width: "64px", backgroundColor: state.subColor}} />
    )}
</ColorConsumer>

 

이번에는 value.action의 함수들을 호출하는 컴포넌트를 추가해 사용해보자

 

색상을 선택할 수 있는 기능을 만들어 함수가 잘 호출되어 색상이 바뀌는지 확인할 수 있다.

색상 선택지 컴포넌트를 만들고, ColorConsumer 로 context 데이터 중 actions를 가져와 사용한다.

 

import { ColorConsumer } from "../contexts/color"

function SelectColors() {
    const colors = ['red', 'orange', 'yellow', 'green','blue']
  return (
    <div>
        <h2>색상 선택</h2>
        <ColorConsumer>
            {({actions}) => {
                return (
                    <div style={{display: "flex"}}>
                        {colors.map(color => {
                            return <div
                                key={color}
                                style={{
                                    background: color,
                                    width: "24px",
                                    height: "24px",
                                    cursor: "pointer",
                                }}
                                onClick={() => actions.setColor(color)}
                                onContextMenu={e => {
                                    e.preventDefault();
                                    actions.setSubColor(color)
                                }}
                            >
                            </div>
                        })}
                    </div>
                )
            }}
        </ColorConsumer>
    </div>
  )
}

export default SelectColors

 

왼쪽클릭(일반클릭) 시 color 가 바뀌도록 setColor 함수를 호출하고, 오른쪽 클릭 시 setSubColor 함수를 호출해 subColor을 변경한다.

 

 

 

4. useContext hook

useContext 라는 훅을 사용하여 Context의 값을 조회할 수도 있다.

    const { state } = useContext(ColorContext)

 

그러면 Provider 컴포넌트로 감싸지 않아도 변수에 할당할 수 있다 🔥

 

 

 

 

 

 

 

 

다음에는 이 Context API를 기반으로 만들어진 리덕스에 대해 공부하겠습니다 👻