Redux ์ •๋ฆฌ๐Ÿ‘ป

๊น€์ง€์›ยท2021๋…„ 11์›” 23์ผ
0

React

๋ชฉ๋ก ๋ณด๊ธฐ
31/31

redux: ๋‹จ๋ฐฉํ–ฅ
action: state๋ฅผ ์–ด๋–ป๊ฒŒ ๋ฐ”๊ฟ€์ง€ ํ–‰๋™์„ ์ ์–ด๋†“์€ ๊ฒƒ
dispatch: ์•ก์…˜ ์‹คํ–‰
reducer: ์•ก์…˜์ด ์‹คํ–‰๋˜๋ฉด ๋ฆฌ๋“€์„œ์—์„œ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ๋‚ด์–ด state๋ฅผ ๋Œ€์ฒด
์ƒˆ๋กœ์šด state๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ๋Š” ์• (๋ถˆ๋ณ€์„ฑ ์กฐ์‹ฌ!)

๋‹จ์ :

  • action์„ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด๋†“์•„์•ผํ•œ๋‹ค.
  • ๋ถˆ๋ณ€์„ฑ์„ ์ง€์ผœ์•ผ์ง€ ํƒ€์ž„๋จธ์‹  ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

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())

๋ฆฌ๋•์Šค ํด๋” ๊ตฌ์กฐ

(๋ฐ์ดํ„ฐ ๋ณ„๋กœ ๋‚˜๋ˆ„๊ธฐ)

  • actions
    • post.js
    • user.js
  • reducers
    • index.js
    • post.js
    • user.js

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))
        }
    }
}

redux-devtools

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)

immer

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
        ....
    }
  }

๋ฆฌ๋•์Šค ์‚ฌ๊ฐ€์˜ ํ•„์š”์„ฑ

๋ฆฌ๋•์Šค ์ž์ฒด๋Š” ๋™๊ธฐ์ ์ธ ์š”์ฒญ๋ฐ–์— ๋ชปํ•จ

์ œ๋„ˆ๋ ˆ์ดํ„ฐ: ํ•จ์ˆ˜ ์‹คํ–‰์„ ์ค‘๊ฐ„์— ๋ฉˆ์ถœ ์ˆ˜ ์žˆ๊ณ  ์›ํ•  ๋•Œ ์žฌ๊ฐœํ•  ์ˆ˜ ์žˆ์–ด ํŽธํ•˜๋‹ค.

  • call: ํ•จ์ˆ˜ ๋™๊ธฐ์  ํ˜ธ์ถœ
  • fork: ํ•จ์ˆ˜ ๋น„๋™๊ธฐ์  ํ˜ธ์ถœ
  • put: ์•ก์…˜ dispatch

0๊ฐœ์˜ ๋Œ“๊ธ€

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด