-
๋ฆฌ๋์ค ํดํทreact 2023. 11. 9. 14:46
๐คทโ๏ธ ๋ฆฌ๋์ค๋?
Javascript ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค
์ปดํฌ๋ํธ๋ค์ด props์์ด state ๊ณต์ ๊ฐ๋ฅํ๊ฒ ํด์ค๋ค!!์ํ ๊ด๋ฆฌ๊ฐ ํ์ํ ์ด์ ๋ ํ๋ก์ ํธ ๊ท๋ชจ๊ฐ ์ปค์ง๋ฉด์ ์ํ ๋ฐ์ดํฐ์ ์ ๋ฌ๊ณผ ์ ๋ฐ์ดํธ๊ฐ ๋ณต์กํด์ง๊ณ , ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์๊ฐ ์ด๋ ค์์ง๊ธฐ ๋๋ฌธ์ด๋ค. Props๋ฅผ ํตํด ์ํ๋ฅผ ์ ๋ฌํ๊ฒ ๋๋ฉด ์ฝ๋๊ฐ ๋ณต์กํด์ง๊ณ , ์ํ ๋ณ๊ฒฝ ์ ๋ถํ์ํ ์ปดํฌ๋ํธ ๋ฆฌ๋ ๋๋ง์ด ๋ฐ์ํ ์ ์๋ค.
=> Redux๋ ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค
๐พ Redux๋ store.js ํ๊ณณ์ state๋ค์ ์ ์ฅํด๋์ด ๋ชจ๋ ์ปดํฌ๋ํธ๋ค์ด ์ง์ ๊ฐ์ ธ๋ค ์ธ์์๋ค!!
(์ฆ, ์ํ๊ด๋ฆฌ๋ฅผ ์ปดํฌ๋ํธ์ ๋ฐ๊นฅ์์ ํ๋ ๊ฒ์)
๐คทโ๏ธ ๋ฆฌ๋์ค ํดํท(Redux-Toolkit) ์ด๋?
ํจ์จ์ ์ธ Redux ๊ฐ๋ฐ์ ์ํ ์ ํฌ์ ๊ฒฌํด๋ฅผ ๋ฐ์ํ, ์ด๊ฒ๋ง์ผ๋ก๋ ์๋ํ๋ ๋๊ตฌ ๋ชจ์, Redux Toolkit์ Redux ๋ก์ง์ ์์ฑํ๊ธฐ ์ํ ํ์ค ๋ฐฉ์์ด ๋๋๋ก ๋ง๋ค์ด์ก๊ณ , ์ฌ์ฉํ๊ธฐ๋ฅผ ๊ฐ๋ ฅํ ์ถ์ฒํ๋ค๊ณ ํจ
๐คทโ๏ธ Redux ์ฌ์ฉํ๊ธฐ
๋ฆฌ๋์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
ํฐ๋ฏธ๋์ ์ ๋ ฅ
npm install redux npm install react-redux (๋ฆฌ์กํธ์ ์ฌ์ฉ์) npm install @reduxjs/toolkit react-redux (๋ฆฌ๋์ค ํดํท ์ฌ์ฉ์)
state slice
๐ข Action
action์ redux์์ ํจ์๋ฅผ ๋ถ๋ฅผ ๋ ์ฐ๋ ๋๋ฒ์งธ parameter ํน์ argument์
์ฆ, store ์ํ์ ๋ณํ๋ฅผ ์ผ์ผํค๋ ๊ฒ์ ์ก์ ์ด๋ผ๊ณ ํ๋คconst reducer =(count=0, action)=>{ return count; }
- action์ ๋ฐ๋์ object ์ฌ์ผ ํจ! string์ด ๋ ์ ์๋ค!
- action์ ๋ฌด์กฐ๊ฑด type์ด ์์ด์ผ ํจ! {type : "ADD"}
- modifier์ communicateํ๋ ๋ฐฉ๋ฒ์ด๋ค~
๐ข Reducer
state(ํ์ฌ์ํ)์ action(type)๋ฅผ ๋ฐ์ ์๋ก์ด ์ํ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค
const reducer = (state, action) => { }
reducer๋ function(ํจ์)์ผ!
๋์ data๋ฅผ modify(์์ )ํ๋!
const reducer = (count = 0, action) => { if (action.type ==="ADD"){ return count + 1; } else if (action.type ==="MINUS"){ return count - 1; } else { return count; } };
=> ์ฌ๊ธฐ์์ state๋ฅผ (count=0)์ผ๋ก ๋ฐ์์ฃผ์๋ค
๐ข Store
Store๋ ์ปดํฌ๋ํธ ์ธ๋ถ์ ์๋ ์ํ ์ ์ฅ์์
Store์์๋ state(ํ์ฌ ์ํ)๋ค, reducer, ๊ทธ๋ฆฌ๊ณ ๋ช ๊ฐ์ง์ ๋ด์ฅ ํจ์๋ฅผ ํฌํจํ๊ณ ์์ (dispatch, Subscribe ๋ฑ๋ฑ...)Redux ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํ์ผ๋ฉด,
๋จผ์ store.js ํ์ผ์ ์์ฑํ๋คimport {createStore} from 'redux'; const reducer = (count = 0, action) => { console.log(count, action) }; const store = createStore(reducer);
createStore๋ก ์ ์ฅ์๋ฅผ ์์ฑํ๋ค
๊ทธ๋ฐ ๋ค์ reducer๋ฅผ ๋ด์ store์ ์ ์ฅํ๋ค๐ข Dispatch
Store์ ๋ด์ฅํจ์
dispatch๋ฅผ ์ด์ฉํด์ ์ฐ๋ฆฌ๋ action์ ๊ฐ์ฒด ํํ๋ก ๋ณด๋ด์ค๋ค
(=์ก์ ์ ๋ฐ์์ํค๋ ์ญํ )store.dispatch(action) ex) store.dispatch({type:"ADD"})
์คํ ์ด์ ์ํ ๋ณํ๊ฐ ํ์ํ๋ค๋ฉด?
=> dispatch๊ฐ ์ก์ (๊ฐ์ฒด ํํ, ex) {type:ADD})์ด๋ผ๋ ๋ฉ์์ง๋ฅผ ์ ๋ฌํด์ ์คํ ์ด์ ์๋ ค ์ค!
๐พ ์ฐ๋ฆฌ๋ dispatch๋ฅผ ํตํด์ ๋ ๋ฐ๊ฟ๊ฑฐ์ผ!๋ผ๊ณ reducer์ ์์ฒญ ๊ฐ๋ฅ!
type ๋ค์ ์ค๋ ๊ฒ์ด ์์ฒญ ๋ฉ์์ง!!๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค!๐ข Subscribe
Store์ ๋ด์ฅํจ์
ํน์ ํจ์ ํํ์ ๊ฐ์ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์์ด
์คํ ์ด์ ์ํ๊ฐ ์ ๋ฐ์ดํธ๋ ๋๋ง๋ค ํน์ ํจ์๊ฐ ํธ์ถ๋๋ค์ฐ๋ฆฌ๊ฐ ์ธ๋ก ์ฌ(store)์ ๊ตฌ๋ ํ๋ฉด ๋ด์ค(state)๊ฐ ์ ๋ฐ์ดํธ ๋ ๋๋ง๋ค
์๋(ํน์ ํจ์ ex) onChange)์ด ํธ์ถ๋๋ค! ๋ผ๊ณ ์๊ฐํ๋ฉด ๋จstore.subscribe(ํน์ ํจ์); ex)store.subscribe(onChange);
โ ๋ง์ฝ์ ๋ค๊ฐ change๋ฅผ ๋์ store์์ ๊ฐ์งํ๊ณ ์ถ๋ค๋ฉด,
⇒ ๊ทธ change๋ฅผ subscibe(๊ตฌ๋ )ํ๋ฉด ๋จ!!
const onChange()=>{ number.innerText = store.getState(); console.log('changed') } store.subscibe(onChange);
=> ์ํ๋ณํ๋ฅผ ๊ฐ์งํ ๋๋ง๋ค store.getState();์ ์ํด ํ์ฌ์ ์ํ์ ํจ๊ป console.log('changed')๊ฐ ๋ํ๋๋ ๋ชจ์ต
์ถ๊ฐ๋ก...
if else๋ฌธ ๋์ case๋ฌธ ์ฌ์ฉํ๊ธฐ
if else๋ฌธ ์ฌ์ฉ
const reducer = (count = 0, action) => { if (action.type ==="ADD"){ return count + 1; } else if (action.type ==="MINUS"){ return count - 1; } else { return count; } };
case๋ฌธ ์ฌ์ฉ
const reducer = (count = 0, action) => { switch (action.type) { case "ADD": return count + 1; case "MINUS": return count - 1; default: return count; } };
if else๋ฌธ๋ณด๋ค case๋ฌธ์ ์ฌ์ฉํ์๋ ์ฝ๋์ ๊ฐ๋ ์ฑ์ด ๋ ๋์
(์ด๋ ๊ฒ์ ์ฐ๋ ์๊ด์ ์์ ๊ฐ์ธ ์ทจํฅ์ ๋ฐ๋ผ ์ฌ์ฉํ๊ธฐ~)
๋ณ์์ ๋ด์ ์ฌ์ฉํด์ action ๊ฐ์ฒด๋ณด๋ด์ฃผ๊ธฐ
๋ณ์ ์ฌ์ฉ
const ADD ="ADD"; const MINUS ="MINUS"; const handleAdd = () => { store.dispatch({ type: ADDD }) }
๋ณ์์ ๋ด์์ฃผ์ด javaScipt๊ฐ ๋ญ๊ฐ ์๋ชป๋์๋ค๊ณ ๋ง์ ํด์ค, string์ ์ฐ๊ฒ ๋๋ฉด type: "ADDD" ์ค๋ฅ๊ฐ ๋จ์ง์์
=> ์ค๋ฅ๋ฅผ ๋นจ๋ฆฌ ํ์ธํ ์ ์๋ค๐คทโ๏ธ ์ ๋ฆฌํ๊ธฐ
Action ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ผ์ด๋๋ ์ฌ๊ฑด์ ๋ํ๋ด๋ ๊ฐ์ฒด
Reducer ์ก์ ์ ๋ฐ๋ผ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ํจ์๋ก, ํ์ฌ ์ํ์ ์ก์ ์ ๋ฐ์ ์๋ก์ด ์ํ๋ฅผ ๋ฐํํจ
Store ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ๋ฅผ ์ ์ฅํ๋ ์ค์ ์ ์ฅ์๋ก, ์ํ ๋ณ๊ฒฝ๊ณผ ๊ด๋ จ๋ ์์ ์ ์ํํจ
Dispatch ์ก์ (๊ฐ์ฒด ํํ)์ ์คํ ์ด์ ๋ณด๋ด ์ํ๋ฅผ ๋ณ๊ฒฝ์์ผ์ค๋ผ๊ณ ์๋ฆผ
Subscribe ์คํ ์ด์ ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ํน์ ํจ์๋ฅผ ์คํํ์ฌ ์ํ ๋ณํ๋ฅผ ๊ฐ์ง๐คทโ๏ธ ํ๋์ ์ ๋ฆฌํ๊ธฐ
๋ฆฌ๋์ค ์ฌ์ฉ ํ๋ฆ ์ ๋ฆฌ
3๊ฐ์ง ์ธ์
initialState ์ด๊ธฐ๊ฐ ์ค์
name์ค์
reducers์ค์
1. slice ์์ฑํ๊ธฐ
index.js
import { createSlice } from '@reduxjs/toolkit' const projectstate = createSlice({ name: 'project', initialState: { title: '์ธ๋ฏธ๋', desc: '์๋ฝ', cnt: 0 }, reducers: { changeTitle: (state, action) => { state.title = action.payload }, changeDesc: (state, action) => { state.desc = action.payload } } }) export const { changeTitle, changeDesc } = projectstate.actions; export default projectstate.reducer;
2. reducer ๋ฑ๋กํ๊ธฐ
store.js
import { configureStore } from '@reduxjs/toolkit'; import projectReducer from './index' export const store = configureStore({ reducer: { project: projectReducer } }) export default store
3. Provider๋ฅผ ์จ์ค๋ค store(์ ์ฅ์) ๊ณต์ ํ๊ธฐ
App.js
import store from './store/store' root.render( <Provider store={store}> <BrowserRouter> <App /> </BrowserRouter> </Provider> );
4. useSelector๋ฅผ ํตํด ๊ณต์ ์ ์ฅ์๋ฅผ ๋ง๋๋ก ๊ฐ์ ธ๋ค ์ธ์์๋ค~
let state = useSelector((state)=>{return state})
header.jsx
import { useDispatch, useSelector } from 'react-redux'; const HeaderNav = (props) => { const dispatch = useDispatch(); const { project = useSelector(state => state.project);
'react' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
ํ์ผ์ ์ฅํ๊ธฐ (0) 2023.11.20 [React] ๋ด๊ฐ ๋ณด๋ ค๊ณ ์ด ๊ฐ๋ฐํ๊ฒฝ ์ ํ ํ๊ธฐ (0) 2023.11.17 [React]props (0) 2023.11.07 React ๋ผ์ฐํฐ : Link & UseNavigate (1) 2023.10.31 useEffect / useCallbackํ๊ธฐ (0) 2023.10.25