TIL | #19 React | Context

trevor1107·2021년 4월 11일
0

2021-04-08(목)

Context

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

언제 Context를 써야 하나?

context는 React 컴포넌트 트리 안에서 전역적(global)이라고 볼 수 있는 데이터를 공유할 수 있도록 고안된 방법이다. 그러한 데이터로는 현재 로그인한 유저, 테마, 선호하는 언어 등이 있다.

테마를 예를들어 한번 알아보자.

context를 사용해서 원하는 값을 컴포넌트 트리의 깊숙한 곳까지 보낼 수 있다.

아래는 context의 데이터로 state와 actions를 넣어주었는데, state에는 말그대로 state 값을 넣어주었고, actions에는 setState 함수를 넣어주었다.

Provider를 이용해서 특정 컴포넌트에게 원하는 값을 전달할 수 있는데. 여기서는 자식으로 있는 녀석에게 전달한다.

결과물

구현

// contexts/color.js
import { createContext, useState } from 'react';

const ColorContext = createContext({
	state: { color: 'black', subcolor: 'red' },
	actions: {
		setColor: () => {},
		setSubcolor: () => {},
	},
});

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 ColorConsumer = ColorContext.Consumer와 같다.
const { Consumer: ColorConsumer } = ColorContext;

export { ColorProvider, ColorConsumer };

export default ColorContext;

아래는 context를 사용하는 컴포넌트이다.
Consumer을 통해서 context의 변화를 구독할 수 있다.
단 조건은 Context.Consumer의 자식은 함수여야한다. 그래서 아래 ColorConsumer 안에는 value라는 매개변수를 받는 화살표함수로 이루어져있다.

// components/ColorBox.js
import React, { useContext } from 'react';
import ColorContext from '../contexts/color';
const ColorBox = () => {
    // 함수형 컴포넌트에서는 Hook 함수를 이용해서
    // 편하게 Context를 사용할 수 있다.
    const { state } = useContext(ColorContext);
    return (
        <>
            <div
                style={{
                    width: '64px',
                    height: '64px',
                    background: state.color,
                }}
            />
            <div
                style={{
                    width: '32px',
                    height: '32px',
                    background: state.subcolor,
                }}
            />
        </>
    );
};

export default ColorBox;

왼쪽 마우스 클릭으로 조금 큰 사각형의 색깔을 바꾸고, 우측 마우스 클릭으로 작은 사각형의 색깔을 바꾸는 로직을 구현한다.

// components/SelectColor.js
import React from 'react';
import { ColorConsumer } from '../contexts/color';
const colors = ['red', 'orange', 'yellow', 'green', 
'blue', 'indigo', 'violet'];

const SelectColors = () => {
    return (
        <div>
            <h2>선택하세요</h2>
            <ColorConsumer>
                {({ actions }) => (
                    <div style={{ display: 'flex' }}>
                        {colors.map((color) => (
                            <div
                                key={color}
                                style={{
                                    background: color,
                                    width: '24px',
                                    height: '24px',
                                    cursor: 'pointer',
                                }}
                                onClick={() => actions.setColor(color)}
                                onContextMenu={(e) => {
                                    e.preventDefault();
                                    actions.setSubcolor(color);
                                }}
                            />
                        ))}
                    </div>
                )}
            </ColorConsumer>
            <hr />
        </div>
    );
};

export default SelectColors;
// App.js
import React from 'react';
import ColorBox from './components/ColorBox';
import { ColorProvider } from './contexts/color';
import SelectColors from './components/SelectColors';

const App = () => {
    return (
        <ColorProvider>
            <div>
                <SelectColors />
                <ColorBox />
            </div>
        </ColorProvider>
    );
};

export default App;
profile
프론트엔드 개발자

0개의 댓글