React로 사이드프로젝트를 하던 중 특정 변수에 대해 거의 모든 컴포넌트에서 참조를 하고 변경시 랜더링해줘야 하는 이슈가 생겼다.
개발 환경과 언어는 MacOS, React(v18.2.0), Typescript(v4.8.4), Redux(v4.2.0)이고, 배포는 docker로 묶어서 EC2에 띄울 예정이다.
그냥 App.tsx에서 useState로 State Hook 만들어서, 변수와 컨트롤러를 만들 수도 있었겠지만 depth가 커지는 컴포넌트가 생기면, 코드 가독성이 저해될 것 같았다.(사실 나만 보는 코드니까 상관은 없지만...)
그래서 상태 관리 라이브러리인 Redux를 사용해봤다. 이전에는 Redux가 react에 종속적인 라이브러리인줄 알았는데, 이번에 공부하며 찾아보니 JS를 위한 상태관리 라이브러리로 본질이 Node.js 모듈이라고 한다.
1. Redux용 폴더를 만들고 상태관리할 변수에 대해서 정의하고, 변수를 컨트롤할 함수도 정의합니다.
// src/store/modules/language.ts
import { ActionType } from "typesafe-actions";
// Actions
const TOENG = "TOENG";
const TOKOR = "TOKOR";
// Action Creator
export const toEnglish = () => {
return {
type: TOENG,
};
};
export const toKorean = () => {
return {
type: TOKOR,
};
};
const actions = { toEnglish, toKorean };
type SetLanguageAction = ActionType<typeof actions>;
const initialState = {
language: "ENG",
};
export default function setLanguage(
state = initialState,
action: SetLanguageAction
) {
switch (action.type) {
case TOENG:
return {
language: "ENG",
};
case TOKOR:
return {
language: "KOR",
};
default:
return state;
}
}
2. 여러개의 상태관리가 중첩될 경우 rootReducer로 combine해서 export 해주게 됩니다.
// src/store/modules/index.ts
import { combineReducers } from "redux";
import setLanguage from "./language";
const rootReducer = combineReducers({
setLanguage,
});
export default rootReducer;
export type RootState = ReturnType<typeof rootReducer>;
3. store 변수에 (2)에서 만단 rootReducer를 불러오고, react-redux에 있는 provider로 <App />을 감싸게 됩니다.
// src/index.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { Provider } from "react-redux";
import { legacy_createStore as createStore } from "redux";
import rootReducer from "./store/modules";
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
const store = createStore(rootReducer);
root.render(
<Provider store={store}>
<App />
</Provider>
);
redux에서 생성한 함수와 변수들을 가져와서 적용하는 부분입니다.
// src/components/atom/Flag.tsx
import React from "react";
import styled from "styled-components";
import { useSelector } from "react-redux";
import { RootState } from "../../store/modules";
import { toEnglish, toKorean } from "../../store/modules/language";
import { useDispatch } from "react-redux";
function Flag() {
const dispatch = useDispatch();
const language = useSelector(
(state: RootState) => state.setLanguage.language
);
return (
<div>
{language === "ENG" ? (
<div onClick={() => dispatch(toKorean())}>
<FlagImage src="img/kr.png" alt="KR"></FlagImage>
</div>
) : (
<div onClick={() => dispatch(toEnglish())}>
<FlagImage src="img/us.png" alt="US"></FlagImage>
</div>
)}
</div>
);
}
const FlagImage = styled.img`
margin: 0 auto;
width: 40px;
height: 40px;
border: 2px solid rgb(0, 0, 0);
border-radius: 50%;
right: 0;
`;
export default Flag;
이런식으로 국기를 누르면 재랜더링 되면서 언어가 바뀌게 설정할 수 있었습니다.
잘못된 부분은 댓글로 피드백 남겨주시면 감사하겠습니다!
'개발 > React' 카테고리의 다른 글
[Web] 12편 - 임시로 React를 https로 호스팅하기, pm2를 곁드려서 서비스하기 (0) | 2022.07.12 |
---|---|
[Web] - 6편 React 기반의 자기소개 페이지 만들기 (5) | 2022.04.16 |
[Web] - 5편 React에서 fullpage.js 적용하기 (0) | 2022.01.31 |
[Web] - 4편 React & MongoDB 설치 (0) | 2022.01.30 |