0. 2단계 context으로 생성한 홈페이지
1. [3단계] 중 [3단계] 구현 & TIL
- redux 브랜치 : 모두 redux 라이브러리를 이용한 코드로 리팩터링
(1) props처럼 계속 부모>자식 컴포넌트로 전달을 안 해도 되는 장점이 있음
(2) 기존에 받아온 데이터의 형식과 리덕스로 전달받은 값이 약간 달라서 헷갈리는 부분이 있었음.
- 예시) context로 한 경우 : data.comment.filter(~~)
- 예시) redux로 한 경우 : data.filter(~~)
(1) index.js
import { Provider } from 'react-redux';
import store from './redux/config/configStore';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
▶ App 하위에서 리덕스의 store 사용 가능하도록 설정
(2) redux폴더 > config 폴더 > configStore.js
import { createStore } from 'redux';
import { combineReducers } from 'redux';
import setComment from '../modules/comments';
import selectMember from '../modules/selectMember';
const rootReducer = combineReducers({ setComment, selectMember });
const store = createStore(rootReducer);
export default store;
▶rootReducer에는 modules 폴더에서 사용하는 모듈을 combineReducers 안에 객체로 넣어 외부에서 사용 가능
▶Store : 중앙 데이터 (state) 관리소
(3-1) redux폴더 > modules 폴더 > comments.js
import DummyData from '../../fakeData.json';
//초기값
const initialState = [...DummyData];
const Write_Comment = 'WriteComment';
const Update_Comment = 'UPdateComment';
//action Creator
//payload는 WriteComments.jsx의 인자
export const WriteComment = (payload) => {
return {
type: Write_Comment,
payload,
};
};
//action Creator
//payload는 DetailsUpdate.jsx의 인자 (수정)
//Details.jsx (삭제)
export const UpdateComment = (payload) => {
console.log('payload', payload);
return {
type: Update_Comment,
payload,
};
};
const setComment = (state = initialState, action) => {
switch (action.type) {
case Write_Comment: //new
return [...state, action.payload];
case Update_Comment:
return [...action.payload];
default:
return state;
}
};
export default setComment;
▶ 초기값을 설정해줘야함 (객체)
▶ Action Creator을 export해서 외부에서 dispatch사용시 action객체의 payload로 전달하는 부분에서 사용
▶ setComment : action객체의 type에 따라 제어
(3-2) redux폴더 > modules 폴더 > selectMember.js
//초기값
const initialState = { member: '하니' };
const memeberChange = 'change';
export const setclickedMember = (payload) => {
return {
type: memeberChange,
payload,
};
};
const selectMember = (state = initialState, action) => {
switch (action.type) {
case memeberChange:
return {
member: action.payload,
};
default:
return state;
}
};
export default selectMember;
▶ 여기는 그룹 멤버를 변화하면 작동하는 모듈
4. Router.js
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Home from '../pages/Home';
import Details from '../pages/Details';
import DetailsUpdate from '../pages/DetailsUpdate';
const Router = () => {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />}></Route>
<Route path="detail/:id" element={<Details />}></Route>
<Route path="update/:id" element={<DetailsUpdate />}></Route>
</Routes>
</BrowserRouter>
);
};
export default Router;
▶ Context API와 마찬가지로 깔끔함
5. WriteComments.jsx
import React, { useEffect } from 'react';
import uuid from 'react-uuid';
import { useState } from 'react';
import { memberList } from '../shared/MemberList';
import { useDispatch, useSelector } from 'react-redux';
import { WriteComment } from '../redux/modules/comments';
function WriteComments() {
const [writer, setWriter] = useState('');
const [content, setContent] = useState('');
const [selectMember, setSelectMember] = useState('하니');
//데이터 가져오기
const data = useSelector((state) => state.setComment);
//redux
const dispatch = useDispatch();
return (
<StDivWrite>
<form
onSubmit={(event) => {
event.preventDefault();
const newComment = {
writer,
content,
member: selectMember,
id: uuid(),
};
dispatch(WriteComment(newComment));
}}
>
▶ 데이터 가져오기 : 리덕스 hook = useSelector(()=>{}) 사용 && import useSelector
▶ action 객체를 store에 전달 : 리덕스 hook = dispatch(); 사용 && import useDispatch
▶ 이외 다른 컴포넌트도 동일 방식 적용
▶ 코드만 리팩토링하여 결과물은 동일.
끝.