์์ํ๋ฉฐ
1ํธ์์ ๋ค๋ฃจ์๋ ๊ธ์์๋ redux-actions
๋ฅผ ์ฌ์ฉํ๋๋ฐ, redux
์ react-redux
๋ชจ๋๋ก๋ ์ถฉ๋ถํ์ง ์์๊น ์ถ์๋ค. ํจํด ์ญ์ ์ข ๋ ์ง๊ด์ ์ผ๋ก ์ดํดํ ์ ์์ผ๋ฉด ์ข์ ๊ฒ ๊ฐ์์ ์ฆ๊ฒจ๋ณด๋ ์ ํ๋ฒ์ Redux ๊ฐ์๋ฅผ ํ ๋ฒ ๋ค์ด๋ดค๋ค.
๋๋ ํ ๋ฆฌ ๊ตฌ์ฑ
store
โmodules
โ index.js
โ test.js
โconfig.js
โindex.js
๊ธฐ์กด์๋ ์ ๊ฐ์ ๊ตฌ์ฑ์ด์๋ค. ์ด๋ฅผ ๊ฐ๋จํ๊ฒ actions์ reducers๋ก ๊ตฌ๋ถํ๋ค.
๊ธฐ๋ณธ ์ค์
1 step reducer ์์ฑ
reducers ํด๋ ๋ด์ counter์ ๋ก๊ทธ์ธ ์ฌ๋ถ๋ฅผ ํ์ธํ๋ isLoggedIn reducer๋ฅผ ๋ง๋ค์ด๋ณด๊ธฐ๋ก ํ๋ค.
// src/reducers/counter.js
const counterReducer = (state = 0, action) => {
switch(action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
}
export default counterReducer;
// src/reducers/isLogged.js
const LoggedReducer = (state = false, action) => {
switch(action.type) {
case 'SIGN_IN':
return !state; // or true
default:
return state;
}
}
export default LoggedReducer;
์ธ์๋ก ๋ฐ๋ state์๋ ์ด๊ธฐ๊ฐ์ ์ค์ ํด์ค ์ ์๋ค. ๋ ๋ฒ์งธ ์ธ์๋ reducer๊ฐ ์คํํ๊ณ ์ ํ๋ action์ ๋ฐ๋๋ค. ๋๋ค switch ๋ฌธ์ ์ฌ์ฉํด action.type์ด ์ด๋ป๊ฒ ๋ค์ด์ค๋์ง์ ๋ฐ๋ผ ๋ฐํํ๋ ๊ฐ์ด ๋ค๋ฅด๋ค. default ๋ถ๋ถ์ ์จ์ฃผ์ง ์์ผ๋ฉด return ๊ฐ์ด undefined
์ผ ๋ ์๋ฌ๋ฅผ ๋ผ ๊ฒ์ด๋ฏ๋ก ์ฃผ์.
์ด๋ ๊ฒ Reducer๋ ์ํฉ์ ๋ฐ๋ผ ์ฌ๋ฌ ๊ฐ๋ฅผ ๊ฐ์ง๊ฒ ๋ ํ ๋ฐ, ์ด๋ ํ ๊ตฐ๋ฐ์ ๋ชจ์ (= combine) ๋ด๋ณด๋ด์ฃผ๋ ์ญํ ์ ํ ํ์ผ์ด ํ์ํ๋ค. reducers ํด๋ ๋ด index.js์ ์๋์ฒ๋ผ ์์ฑํ๋ค.
step 2 combineReducer
import counterReducer from './counter';
import LoggedReducer from './isLogged';
import { combineReducers } from 'redux'
const rootReducer = combineReducers({
counter : counterReducer,
isLogged : LoggedReducer
})
export default rootReducer;
redux
๋ชจ๋์ด ์ ๊ณตํ๋ combineReducers
ํจ์๋ฅผ ์ฌ์ฉํ๋ค. ๊ตณ์ด ๊ฐ ๋ฆฌ๋์์ ์ด๋ฆ์ ๋ถ์ด์ง ์๋๋ค ํ๋ฉด ์๋์ฒ๋ผ ์์ฑํด๋ ๋๋ค.
const rootReducer = combineReducers({
counterReducer, // same as counterReducer : counterReducer
LoggedReducer // same as LoggedReducer : LoggedReducer
step 3 actions
reducer์ ์ธ์๊ฐ ๋๋ actions๋ฅผ ์ ์ํ๊ธฐ ์ํด actions ํด๋์ index.js๋ฅผ ์๋์ฒ๋ผ ์์ฑํ๋ค.
export const increment = () => {
return {
type: 'INCREMENT'
}
}
export const decrement = () => {
return {
type: 'DECREMENT'
}
}
์ฌ๊ธฐ์ type
์ ์ผ์ข
์ 'name'์ผ๋ก, ๊ด์ต์ ์ผ๋ก type
์ด๋ผ ์ ์ง๋ง name ๋ฑ์ผ๋ก ์ ์ด๋ ๋ฌด๋ฐฉํ๋ค.
step 4 index.js์์ store๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ๊ธฐ๋ณธ ์ค์ ํ๊ธฐ
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { createStore } from 'redux';
import allReducers from './reducers'; // webpack automatically detects whether its folder has index.js file. so this can be omitted
import { Provider } from 'react-redux'; // Connects our global states to our entire App.
const store = createStore(allReducers, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
์ ์ฃผ์์์ ์ ์ด๋ ๊ฒ์ฒ๋ผ ./reducer
๋ผ๊ณ ๋ง ์ ์ด๋ ๊ธฐ๋ณธ index.js ํ์ผ์ ์์์ ๊ฐ์งํ๊ณ importํ๋ค. ./reducers/index.js
์ ๋์ผํ๋ค.
store๋ฅผ ๋ง๋ค๊ณ -> combinedํ reducer๋ฅผ import ํ๊ณ -> ์ด๋ ๊ฒ ๊ฐ์ ธ์จ global states๋ฅผ ์ฑ๊ณผ ์ฐ๊ฒฐํ๊ธฐ ์ํด Provider๋ฅผ importํ๋ ์์ด๋ค.
์ฌ๊ธฐ์ createStore
ํจ์์ ๋ ๋ฒ์งธ ์ธ์๋ก ๋ค์ด์ค๋ devtool ๊ด๋ จ ์ค๋ช
์ 1ํธ์ ์
๋ฐ์ดํธํด๋์๋ค.
step 5 ์ปดํฌ๋ํธ์์ ์ค์ ๋ก ์ฌ์ฉํด๋ณด๊ธฐ
import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './actions';
function App() {
const counter = useSelector(state => state.counter)
const isLogged = useSelector(state => state.isLogged)
const dispatch = useDispatch();
return (
<div className="App">
<h1>Counter : {counter}</h1>
<button onClick={() => {
dispatch(increment())
}}>+</button>
<button onClick={() => {
dispatch(decrement())
}}>-</button>
{isLogged ? <h1>valuable information I shouldn't see</h1> : ''}
</div>
);
}
export default App;
global state์ ์ ๊ทผํ๊ธฐ ์ํด react-redux๊ฐ ์ ๊ณตํ๋ useSelector
๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก dispatch๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด react-redux๊ฐ ์ ๊ณตํ๋ useDispatch
๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
๊ฐ actions๋ ๋ถ๋ฌ์์ฃผ๊ธฐ๋ง ํ๋ฉด, ์ค์ ์ปดํฌ๋ํธ์์๋ ์์ฒ๋ผ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค. dispatch()
๋ฅผ ํตํด ์ ์ฒด redux์ ํ๋ฆ์ ์ผ์ผํค๊ณ , actions๋ฅผ ์ธ์๋ก ๋ฐ๋๋ค. ๊ฐ ์ธ์๋ ๋ช
์๋ ์์์ type์ ๋ฐํํ๊ณ , ์ค์ ํด๋น reducer์ switch ๋ฌธ์ ํตํด ๊ฐ์ง๋ case์ ๋ฐ๋ผ state์ ๋ณํ๋ฅผ ์ค๋ค.
devTool์ ์ฒ์ ์จ๋ดค๋๋ฐ, ์ด๋ ๊ฒ ์ผ์ด๋ ๋ณํ๋ฅผ ๋์ผ๋ก ํ์ธํ ์ ์๊ฒ ํด์ค๋ค.