오늘 실습할 내용
redux, react-redux 로 App.js 에 간단한 다크모드, 일반모드 기능을 구현해볼 것이다.
- 프로젝트 경로 : C:\react_redux
- react - app 명 : darkmode
- Node 버전 : 20. 10. 0
- IDE : 인텔리제이
- 경로
- 1-리액트 앱, 2-리덕스, 3-리액트-리덕스 이 3가지만 설치할 예정
- 1-인텔리제이 터미널로 리액트 프로젝트 설치
npx create-react-app darkmode
- 제대로 설치되었는지 npm start 로 테스트
npm start
정상동작 확인했으면 control + c -> y 로 진행 중인 프로젝트 종료시키고 남은 라이브러리 마저 설치
- 2-리덕스(redux) 설치
npm install --save redux
- 3- 리액트-리덕스 설치(react-redux)
npm install --save react-redux
- ★ src/ 경로에 actions 디렉토리와 reducers 디렉토리를 만들어주자
: 개인 학습 겸 업로드된 게시물이기 때문에 이론적인 설명이 많이 부족할 수 있음 주의 ㅠㅠ
src/actions 의 용도 -> 리덕스state(전역변수)를 변경시키는 리덕스 함수에 들어갈 파라미터 js 파일 경로 (해당 경로네 js 파일은 리덕스함수의 파라미터를 유사 프로퍼티처럼 사용하기 위함)
src/reducers 의 용도 -> 리덕스state 와 리덕스 함수를 정의하는 js 파일 경로
- src/actions/index.js 파일 생성 및 정의 (리덕스 함수에 들어갈 파라미터 정의)
- src/ actions/ index.js
export const DARK = "DARK"; // 다크모드 변수 : 유사 프로퍼티
export const NORMAL = "NORMAL"; // 일반모드 변수 : 유사 프로퍼티
export const getDarkMode = () => { // 다크모드 변수 값 가져오는 함수 정의
return {
type : DARK
}
}
export const getNormalMode = () => { // 일반모드 변수 값 가져온느 변수 정의
return {
type : NORMAL
}
}
- src/reducers/ 경로에 index.js 파일 생성 -> 리덕스 상태 정의 및 리덕스 함수 정의할 js 파일
- src/ reducers/ index.js
import {combineReducers} from "redux";
import {DARK, getDarkMode, getNormalMode, NORMAL} from "../actions";
const initState ={ // 최초 리덕스 state 정의
mode : NORMAL // default state 는 일반모드
};
/**
* @param state
* @param action
* 파라미터로 받은 action 값이 DARK 냐 NOLMAL 이냐에 따라
* @returns mode
*/
const data = (state = initState, action) => {
if(action.type === DARK) { // switch 문 써도 됨.
return state, {
mode : getDarkMode().type
}
}
else if(action.type === NORMAL) {
return state, {
mode : getNormalMode().type
}
} else {
return state, {
mode : getNormalMode().type
}
}
}
const App = combineReducers({ // combinReducers 사용하여 하나의 큰 리듀서로 묶어주는 작업
data
});
export default App;
- 이제 간단한 다크모드 ,일반모드 테스트를 진행하기 위해 src/ index.js 와 App.js 파일을 수정
- src/ index.js
== 리덕스 스테이트와 함수가 저장되고 보관되는 곳을 store 라고 한다.
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {createStore} from "redux";
import reducers from "./reducers"; // 리덕스 스테이스, 함수 임포트 dl
// 모든 하위 컴포넌트에서 store 에 접근가능하도록 사용
// react-redux 설치 안 하고 그냥 redux만 설치하는 경우
// 자식 컴포넌트에 props로 store를 계속 넘겨주어야 하는 번거로움이 생기는데 react-redux의 Provider를 사용하면 이런 문제는 간단히 해결된다
import {Provider} from "react-redux";
const store = createStore(reducers) // src/reducers 하위에 있는 모든 js (리덕스 state 와 리덕스 함수를 이제부터 스토어로 관리하겠다는 뜻)
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
- 이제 다크모드 / 일반모드를 확인해볼 뷰를 App.js 에다가 바로 작성해서 테스트 해보자
- App.js 수정
import logo from './logo.svg';
import './App.css';
import {DARK, getDarkMode, getNormalMode, NORMAL} from "./actions";
import {useEffect, useState} from "react";
import {useDispatch, useSelector} from "react-redux";
import {combineReducers} from "redux";
function App(props) {
const dispatch = useDispatch();
const displayMode = useSelector(state => state.data.mode);
const [backGroundColor, setBackGroundColor] = useState("white");
const [color, setColor] = useState("black");
// 분명 상위 src/index.js 에서 store 만들어서 props 로 넘겨줬는데 props.store에 접근을 못한다...
// 그래서 위에 useSelector 와 useDispatch로 대신했다..
// const store = props.store; // src/index.js 에서 Provider로 넘겨준 store;
// 혹시 모르니깐 src/ index.js 의 <Provider store={store}></Provider> 코드 부분은 지우지 말고 남기자
const changeDisplayMode = (mode) => {
if(mode == DARK) {
//store.dispatch(getDarkMode());
dispatch(getDarkMode());
}
if(mode == NORMAL) {
// store.dispatch(getNormalMode());
dispatch(getNormalMode());
}
}
const setDisplayByGlobalState = () => {
console.log(displayMode);
if (displayMode === 'DARK') {
setBackGroundColor("black");
setColor("white");
} else if (displayMode === 'NORMAL') {
setBackGroundColor("white");
setColor("black");
} else {
setBackGroundColor("white");
setColor("black");
}
}
useEffect(() => {
setDisplayByGlobalState();
}, []);
useEffect(() => { // 리덕스 상태 바뀌면 재렌더링
// console.log(store.getState().data.mode);
// console.log(displayMode);
setDisplayByGlobalState();
}, [displayMode])
return (
<div
className="App"
style={{display:"table", margin:"auto", textAlign:"center"}}
>
<button
onClick={() => {
changeDisplayMode(DARK);
}}>다크모드
</button>
<button
onClick={() =>{
changeDisplayMode(NORMAL);
}}>
일반모드
</button>
<div
style={{
width:"100%",
height:"15em",
border: '1px solid black',
background: `${backGroundColor}`
}}>
<p
style={{
color: `${color}`
}}>
redux, react-redux 실습 : 다크모드 / 일반모드
</p>
</div>
</div>
);
}
export default App;
- 최초 렌더링 시
- 다크모드 클릭 시
- 일반모드 클릭 시
-- 실습 끝
+
원래 Provider 로 props.store로 리덕스 스테이트에 접근하려고 했으나
props 상속이 안 되는 이슈가 발생해
useSelector 와 useDispatch 사용
자세한 내용은 App.js 주석 참고
'react' 카테고리의 다른 글
리액트(react) - 리코일(Recoil) 과 Selector 사용 예제 학습 (8) | 2024.11.14 |
---|---|
리액트(react) - 자식 컴포넌트에서 부모 컴포넌트 state 변경 (2) | 2024.08.20 |
[토이프로젝트-프론트(react)] 프로젝트명 : 커뮤니티 - 업데이트 중 (3) | 2024.07.21 |
node 모듈 재 설치 하는 법 (0) | 2024.07.21 |
리액트(React) Example 200 - # 081 ~ 083 react-redux 스토어 데이터 상속/사용/변경 (0) | 2024.04.24 |