React

redux-promise

안자바먹지 2020. 12. 18. 17:16
728x90

로그인 페이지를 구현하며 리덕스 공부중 이해가 가지 않은 부분이 있었다. 

아래 소스 처럼 액션생성함수에선 단지 payload에 Promise 객체를 담아

액션 객체 자체를 리턴하는데 LoginPage 컴포넌트에서 dispatch를 호출하면

왜 Promise 객체가 리턴되는가? 였다.

 

// 액션함수
// src/actions/user_action.js

import axios from 'axios'
import { LOGIN_USER, REGISTER_USER, AUTH_USER } from './types'

export function loginUser(dataToSubmit) {
  const request = axios
    .post('/api/users/login', dataToSubmit)
    .then((response) => response.data)

  return {
    type: LOGIN_USER,
    payload: request,
  }
}

 

// 로그인페이지 컴포넌트
// src/components/views/LoginPage/LoginPage.js

import React, { useState } from 'react'
import { useDispatch } from 'react-redux'
import { loginUser } from '../../../_actions/user_action'
import { withRouter } from 'react-router-dom'

function LoginPage(props) {
  const dispatch = useDispatch()

  const [Email, setEmail] = useState('')
  const [Password, setPassword] = useState('')

  ... 생략

  const onSubmitHandler = (event) => {
    event.preventDefault()

    const body = {
      email: Email,
      password: Password,
    }
    
    dispatch(loginUser(body)).then((response) => {
      if (response.payload.loginSuccess) {
        props.history.push('/')
      } else {
        alert('Error')
      }
    })
  }

  return (
    ... 생략
  )
}

export default withRouter(LoginPage)

 

// user 리듀서
// src/reducers/user_reducer.js

import { LOGIN_USER, REGISTER_USER, AUTH_USER } from '../_actions/types'

export default function userReducer(state = {}, action) {
  switch (action.type) {
    case LOGIN_USER:
      return { ...state, loginSuccess: action.payload }

    default:
      return state
  }
}

 

이 점에 대해서 찾아보니 바로 redux-promise 미들웨어 때문이었다.

공식문서에서 아래와 같이 확인할 수 있었다.

 

www.npmjs.com/package/redux-promise

 

redux-promise

FSA-compliant promise middleware for Redux.

www.npmjs.com

The default export is a middleware function. If it receives a promise, it will dispatch the resolved value of the promise. It will not dispatch anything if the promise rejects.

If it receives an Flux Standard Action whose payload is a promise, it will either

  • dispatch a copy of the action with the resolved value of the promise, and set status to success.
  • dispatch a copy of the action with the rejected value of the promise, and set status to error.

The middleware returns a promise to the caller so that it can wait for the operation to finish before continuing. This is especially useful for server-side rendering. If you find that a promise is not being returned, ensure that all middleware before it in the chain is also returning its next() call to the caller.

 


 

즉, payload에 Promise가 담겨 있고 이 Promise가 정상적으로 동작했으면 resolve된 데이터가 반환된다.

그래서 user 리듀서에서 action.payload 에 resolve된 서버의 요청값이 들어 있다. 

 

redux-promise 미들웨어를 지우고 테스트 해본 결과 리듀서의 actions.payload엔 Promise의 resolve 된 값이 아니라 Promise 자체가 들어있었다.

 

로그인페이지 컴포넌트에서도 마찬가지로 redux-promise 미들웨어를 지우면 Promise가 리턴되는게 아니라 액션객체 자체가 반환되어 .then을 사용할 수 없다.  

728x90