상태관리가 복잡해지고, 규모가 커질 때는 redux를 쓴당.
어렵다기 보다는 프레임워크 처럼 세팅 과 사용방식에 익숙해지는 것이 뽀인또인데,
초보자에게는 상당히 아주 상당히 낯선 느낌이 문제당.
낯선 그 느끼미 게으른 뇌에 이건 헷깔리꽁 어렵넹! 이라는 잘못된 결론을 내려버린당.
마치 눈 앞에 오르지 못할 정도로 높아 보이는 산이 있는데, 가보면 땀 좀 빼면 되는데,
게으른 뇌가 산 입구에서 막걸리나 한잔 할까라고 유혹의 두 손을 마구 흔들어 된당.
이런 경우에는 헷갈리지 않게 자신만의 순서(꼭 추천 순서가 아니어도 당근 됨!)를
정해서 몇번 반복해서 손과 눈의 콜라보를 먼저 성취하는 거이 좋을 지어다.
useReducer를 이전에 사용해 본 경험이 있다면 많은 도움이 될꺼당.
상태(state), 리듀서(reducer), 디스패치(dispatch), 액션(action)이 떠올라야만 한당.
0. 사전준비
디렉토리를 1개 만들고, 해당 디렉토리에 아래 명령어로 vite 프로젝트를 생성하고,
react / javascript를 선택하장.(typescript는 관심 외 코드 가 더 필요해서 여기선 회피한당.)
tailwindcss 설정은 되어 있다 가정하겠당.
npx create-vite@latest .
1. 설치
npm install @reduxjs/toolkit react-redux
2. store 생성
store는 app당 1개만 있는걸 권장 한당. 그리하여 관례적으로 src 아래에 app 폴더를 만들고,
그 안에 store.js를 일단 아래 처럼 만든당.
store.js
import { configureStore } from "@reduxjs/toolkit" const store = configureStore({ reducer:{ } }) export default store
3. provider 생성
main.jsx에 아래 처럼 Provider를 제공하고, store를 연결시키자.
이제 Provider로 둘러싸인 App에 들어가는 컴포넌트는 store에 다이렉트로 접근할 수 있다.
Props Drilling이 아니고, 중앙 관리가 핵심이당.
main.jsx
import { createRoot } from 'react-dom/client' import App from './App.jsx' import './index.css' import { Provider } from 'react-redux' import store from './app/store.js' createRoot(document.getElementById('root')).render( <Provider store={store}> <App /> </Provider> )
4. slice 생성
slice는 store(가게)에 가면 상품을 분류해서 코너별로 나열한다. 코너는 1개~여러개당.
그런 코너와 비슷하게 데이터를 분류한 코너를 slice라 생각하면 좋을 것 같당.
Redux에서 slice는 reducer와 action creator의 통합으로 보면 좋당.
slice를 만들 땐 보통 features란 폴더를 만들고, 그 안에서 폴더를 만들어서 분류한다.
features 안에 friends란 폴더를 만들고, friendSlice.js 파일을 아래 처럼 맹글장
friendSlice.js
import { createSlice } from "@reduxjs/toolkit"; const initialState = { friends: [ { id: 1, name: "경미니", song: "그리 미누", color:"green" }, { id: 2, name: "로제", song: "ground", color:"black" }, { id: 3, name: "원영", song: "iam" , color:"gold"}, { id: 4, name: "제니", song: "mantra" , color:"pink"}, { id: 5, name: "카리나", song: "nova" , color:"blue"} ] } // slice 만들어 수출 export const friendSlice = createSlice({ name: "friend", initialState, reducers: { addFriend: (state, action) => { state.friends = [action.payload, ...state.friends] } }, extraReducers:()=>{} }) // action 추출하여 수출 export const { addFriend } = friendSlice.actions // reducer 디폴트 수출 export default friendSlice.reducer
5. slice를 store에 등록
store.js
import { configureStore } from "@reduxjs/toolkit" import friendReducer from "../features/friends/friendSlice" const store = configureStore({ reducer:{ "friend": friendReducer } }) export default store
6. useSelector 와 useDispatcher 사용
여기까지 왔던 이유당. 세팅만 잘 되어 있다면,
useSelector와 useDispatcher를 이용해서 어디서든 편하게 쉽게 상태 변경이 가능하당.
App.jsx
import { useDispatch, useSelector } from "react-redux"; import { addFriend } from "./features/friends/friendSlice"; import { useRef } from "react"; function App() { const { friends } = useSelector((state) => state.friend); const dispatch = useDispatch(); const myForm = useRef(); const addNew = (e) => { e.preventDefault(); const formData = new FormData(myForm.current); // 맥스 id값 찾기, key값 중복 없겡, uuid 모듈 사용해도 됨 let maxId = friends[0].id; friends.forEach((friend) => { maxId = maxId < friend.id ? friend.id : maxId; }); dispatch( addFriend({ id: maxId + 1, name: formData.get("fname"), song: formData.get("fsong"), color: formData.get("fcolor"), }) ); // 입력 값들 초기화 myForm.current.fname.value = ""; myForm.current.fsong.value = ""; myForm.current.fcolor.value = "#000000"; }; return ( <> <h1 id="title">리덕스 연습</h1> <hr /> <form ref={myForm} onSubmit={addNew}> 이름 <input type="text" autoFocus name="fname" required /> <br /> 노래 <input type="text" name="fsong" required /> <br /> 칼라 <input type="color" name="fcolor" /> <br /> <button type="submit">추강</button> </form> <hr /> <div> {friends.map((friend) => ( <div key={friend.id} className="friend"> <h1>{friend.name}</h1> <h2 style={{ color: friend.color }}>{friend.song}</h2> </div> ))} </div> </> ); } export default App;
7. style
이거슨 덤이당. 아마 화면이 정말 못 생겨서 화가 날거당.
아래는 내가 할 수 있는 나름 최선임을 난 부정하지 못한당. 받아들이장.
index.css
@import "tailwindcss"; #title { @apply text-3xl } hr { @apply border-4 m-2 } input[type=text] { @apply border-2 border-gray-400 mb-1 } button { @apply rounded border-1 w-20 ml-20 } .friend { @apply border-amber-400 border-4 mb-5 text-center }
결과는 나의 경우 아래 처럼 보인당. 역시 디자인은 훌륭하지 못하당.
여기까지 했다면 훌륭하당. 하지만
Redux는 여기서 끝은 아니당. Redux는 비동기를 처리하는 방식도 제공하는데
(물론 useEffect를 잘 사용한다면 그걸로 처리 할 수동 있당.)
slice 코드에 있는 extraReducers 와 createAsyncThunk 함수를 이용해야 하는데..
오늘은 여기까지만으로도 훌륭하니, 보고 또 보고, 다음글에서 또 보장
혹 시간이 풍년이라면(데이트 신청에 까였다거나, 실연의 아픔이 깊거나,
산삼을 먹어서 잠이 오지 않거나, 갑자기 영어 공부 생각이 난다거나 등등...)
괘니 아래 링크도 가서 읽어 보장.
https://redux-toolkit.js.org/tutorials/quick-start
로제(rosie)는 현존 내가 가장 좋아하는 음색을 가졌당.
귀는 프리 패스하고 , 심장을 직격 찌리릿 번개 지지미 핵 태우미당.
그럼에도 내게 number one girl은 아닐 girl.~~
number one girl? Who are you? => ??Jean
그럴 girl! 반복(repeat)은 세뇌를 부른다.
number one 일 girl!! , 넌 number one이 아닐 girl!!~~
number one을 또 만들고 또 만들어 number one group 장부를 만들자~
커지고 커지면 대 장부당!~~
역시 모든 글은 아무말 대잔치로 끝날 girl !!
https://www.youtube.com/watch?v=qCepOLkcF_A
CSS 애니메이션 갑자기? (Spinner) (0) | 2025.03.07 |
---|---|
React(리액트) 티키타카 22 (Redux -2) (0) | 2025.03.05 |
도커(Docker) 이미지로 맹글깅 (0) | 2025.02.20 |
React(리액트) 티키타카 20 ( useState 훅 동작 감 잡아보기) (0) | 2024.12.30 |
React(리액트) 티키타카 19 ( FullCalendar 풀캘린더) (3) | 2024.12.29 |