React에서 ServerSideRendering을 하기위해 동적 Context API에 대해 알아보겠습니다.
import React, { 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 { Consumer: ColorConsumer } = ColorContext;
// ColorProvider와 ColorConsumer 내보내기
export { ColorConsumer, ColorProvider };
export default ColorContext;
위 파일에서 ColorProvider라는 컴포넌트를 새로 작성해 주었습니다. 그리고 그 컴포넌트에서는 ColorContext.Provider를 랜더링 하고있습니다. 이 Provider의 value에는 상태는 state로, 업데이터 함수는 action으로 묶어서 전달하고 있습니다. Context에서 값을 동적으로 사용할 때 반드시 묶어줄 필요는 없지만, 이렇게 state와 actions 객체를 따로따로 분리해 주면 나중에 다른 컴포넌트에서 Context의 값을 사용할 때 편합니다.
추가로 createContext를 사용할 때 기본값으로 사용할 객체 또한 수정하였습니다. createContext의 기본값은 실제 Provider의 value에 넣는 객체의 형태와 일치시켜 주는 것이 좋습니다. 그렇게 하면 Context코드를 볼 때 내부 값이 어떻게 구성되어 있는지 파악하기도 쉽고, 실수로 Provider를 사용하지 않았을 떄 리액트 애플리케이션에서 에러가 발생하지 않습니다.
import React from 'react';
import ColorBox from 'components/ColorBox';
import { ColorProvider } from 'contexts/color';
import SelectColors from 'components/SelectColors';
// Provider를 사용해서 Context의 value를 변경할 수 있다.
const App = () => (
<ColorProvider>
<div>
<SelectColors />
<ColorBox />
</div>
</ColorProvider>
);
export default App;
// < Context Api 정리 >
// 컴포넌트의 구조가 꽤 간단하고 다루는 상태의 종류가 그다지 많지 않다면
// 굳이 Context를 사용할 필요는 없습니다.
// 하지만 전역적으로 여기저기서 사용되는 상태가 있고 컴포넌트의 개수가
// 많은 상황이라면 Context Api를 사용하는 것을 권합니다.
// 다음에는 Redux라는 상태 관리 라이브러리를 배운다. -> Context기반이다
// 단순한 전역 상태 관리라면 이번에 배운 Context API로 리덕스를 대체할 수도 있습니다.
// 하지만 리덕스는 더욱 향상된 미들웨어 기능, 강력한 개발자 도구, 코드의 높은 유지 보수성을 제공하기 때문에
// 모든 상황에 대해 대체가 가능하지는 않습니다.
또한 ColorProvider를 불러와서 App의 최상위 container로 맊아 줍니다.
import React, { useContext } from 'react';
import { ColorConsumer } from '../contexts/color';
// 훅 사용
const ColorBox = () => (
<ColorConsumer>
{({ state }) => (
<>
<div
style={{ width: '64px', height: '64px', background: state.color }}
/>
<div
style={{ width: '64px', height: '64px', background: state.subcolor }}
/>
</>
)}
</ColorConsumer>
);
export default ColorBox;
그 후에는 이제 ColorBox 컴포넌트에 ColorConsumer를 사용해 줍니다. 즉 => Provider에서 제공한 color와 subcolor를 사용할 수 있습니다.
import { ColorConsumer } from 'contexts/color';
import React from 'react';
const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'];
// 마우스 왼쪽 버튼을 클릭하면 큰 정사각형의 색상을 변경
// 마우스 오른쪽 버튼을 클릭하면 작은 정사각형의 색상을 변경
const componentName = () => (
<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 componentName;
그 후 위와 동일하게 action을 활용하여 color selector를 만들어 줍니다.
useContext
또한 useContext를 활용하여 상태관리를 더 효율적이게 할 수 있습니다.
import ColorContext from 'contexts/color';
import React, { useContext } from 'react';
// 훅 사용
const ColorBox = () => {
const { state } = useContext(ColorContext);
return (
<>
<div style={{ width: '64px', height: '64px', background: state.color }} />
<div
style={{
width: '64px',
height: '64px',
background: state.subcolor,
}}
/>
</>
);
};
export default ColorBox;
'React > ReactJs' 카테고리의 다른 글
React - redux ( util_Version ) (0) | 2022.02.21 |
---|---|
React - redux (0) | 2022.02.21 |
styled-component의 동작방식 (0) | 2022.02.21 |
SPA기반 SSR구현하기 - 3 (0) | 2022.02.20 |
SPA기반 SSR 구현하기 - 2 (0) | 2022.02.19 |