redux: ๋จ๋ฐฉํฅ
action: state๋ฅผ ์ด๋ป๊ฒ ๋ฐ๊ฟ์ง ํ๋์ ์ ์ด๋์ ๊ฒ
dispatch: ์ก์
์คํ
reducer: ์ก์
์ด ์คํ๋๋ฉด ๋ฆฌ๋์์์ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ๋ด์ด state๋ฅผ ๋์ฒด
์๋ก์ด state๋ฅผ ๋ง๋ค์ด ์ฃผ๋ ์ (๋ถ๋ณ์ฑ ์กฐ์ฌ!)
๋จ์ :
const {createStore} = require('redux')
const reducer = (prevState, action) => {
switch(action.type){
case 'LOG_IN':
return {
...prevState,
user: action.data,
}
case 'ADD_POST':
return{
...prevState,
posts: [...prevState.posts,action.data]
}
case 'LOG_OUT':
return{
...prevState,
user: null
}
default:
return prevState
}
}
const initialState = {
user: null,
posts: []
}
const store = createStore(reducer,initialState)
store.subscribe(()=>{ //react-reudx ์์ ๋ค์ด์์
console.log('changed') //ํ๋ฉด ๋ฐ๊ฟ์ฃผ๋ ์ฝ๋ ์ฌ๊ธฐ์
})
console.log(store.getState())
//action = ๊ฐ์ฒด
const login = data => {
return {
type:'LOG_IN',
data
}
}
const logout = () => {
return {
type:'LOG_OUT'
}
}
const addPost = data => {
return {
type:'ADD_POST',
data
}
}
store.dispatch(login({
id: 1,
name:'jiwon',
admin: true
}))
console.log(store.getState())
store.dispatch(addPost({
userId: 1,
id: 1,
content: '์๋
ํ์ธ์ ๋ฆฌ๋์ค'
}))
store.dispatch(addPost({
userId: 1,
id: 2,
content: '๋๋ฒ์งธ ๋ฆฌ๋์ค'
}))
console.log(store.getState())
store.dispatch(logout())
console.log(store.getState())
(๋ฐ์ดํฐ ๋ณ๋ก ๋๋๊ธฐ)
index.js
์ฌ๋ฌ ๊ฐ์ ๋ฆฌ๋์๋ฅผ ํฉ์น ๋๋ combineReducers
์ฌ์ฉ
reducers/index.js
const {combineReducers} = require('redux')
const userReducer = require('./user')
const postReducer = require('./post')
module.exports = combineReducers({
user: userReducer,
posts:postReducer
})
๋ฏธ๋ค์จ์ด๋ ์ผ๋จ ํจ์๋ก ๋์ด์๋ค.
const firstMiddleware = store => next => action => {
console.log('๋ก๊น
์ฐ๋ ๋ฏธ๋ค์จ์ด', action)
// ์
next(action)//next = distpatch
// ๋ค๋ก ๊ธฐ๋ฅ ์ถ๊ฐ ๊ฐ๋ฅ
}
function firstMiddleware(store){
return function (next){
return function(action){
}
}
}
๋น๋๊ธฐ์ผ๋๋ ํจ์๋ก action์ ๋ณด๋ด์ thunk๊ฐ ์คํ์ ํด์ค๋ค
const thunkMiddleware = store => dispatch => action => {
if(typeof action === "function"){ //๋น๋๊ธฐ
return action(store.dispatch, store,getState)
}
return dispatch(action)
}
login action
const logIn = (data) => { //async action creator
return (dispatch, getState) => {
dispatch(logInRequest(data))
try{
setTimeout(()=>{
dispatch(logInSuccess({
userId: 1,
nickname: 'jiji'
}))
},2000)
}
catch (e) {
dispatch(logInFailure(e))
}
}
}
npm i reudx-devtools-extension -D
const { composeWithDevTools } = require('redux-devtools-extension')
const enhancer = process.env.NODE_ENV === "production" ?
compose(
applyMiddleware(
firstMiddleware,
thunkMiddleware,
)
)
: composeWithDevTools(
applyMiddleware(
firstMiddleware,
thunkMiddleware,
)
)
const store = createStore(reducer, initialState, enhancer)
npm i immer
๊ธฐ๋ณธ ํํ
nextState = produce(prevState, (drfat)=>{})
switch
๋ฌธ์ produce ์์ ๋ฃ์ด๋ฒ๋ฆฌ๊ธฐ
const produce = require('immer')
const userReducer = (prevState=initialState, action) => {
return produce(prevState, draft => {
switch(action.type){
case 'LOG_IN_REQUEST':
draft.data = null
draft.isLoggingIn = true
break
....
}
}
๋ฆฌ๋์ค ์์ฒด๋ ๋๊ธฐ์ ์ธ ์์ฒญ๋ฐ์ ๋ชปํจ
์ ๋๋ ์ดํฐ: ํจ์ ์คํ์ ์ค๊ฐ์ ๋ฉ์ถ ์ ์๊ณ ์ํ ๋ ์ฌ๊ฐํ ์ ์์ด ํธํ๋ค.