상태관리가 복잡해지고, 규모가 커질 때는 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 dispathch = useDispatch();
const myForm = useRef();
const addNew = (e)=>{
e.preventDefault();
const formData = new FormData(myForm.current)
dispatch(addFriend({
id:friends[friends.length -1].id+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
React(리액트) 티키타카 21 (Redux -2) (0) | 2025.03.05 |
---|---|
도커(Docker) 이미지로 맹글깅 (0) | 2025.02.20 |
React(리액트) 티키타카 20 ( useState 훅 동작 감 잡아보기) (1) | 2024.12.30 |
React(리액트) 티키타카 19 ( FullCalendar) (3) | 2024.12.29 |
React(리액트) 티키타카 18 ( rc-tree 트리 컴포넌트) (6) | 2024.12.25 |