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 |