Skip to content

2차 스프린트 01 09 코드리뷰

Kim-GeonHo edited this page Jan 12, 2022 · 2 revisions

사전 지식

  • Redux Toolkit

redux > store.ts

import { configureStore } from '@reduxjs/toolkit'
import authReducer from './auth/authSlice'

const store = configureStore({
  reducer: {
    auth: authReducer,
  },
})

export default store
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch

우선 configureStore를 사용하여 store를 생성하는 것에 집중합니다.
안에는 reducer가 정의돼있고 현재 auth 만 존재합니다.
initial state가 정의돼있지 않은데 이는 SSR을 구현할 필요가 있을 때, 서버에서 보내주는 initial state을 정의해주면 됩니다.
저희는 현재까진 쓰지 않습니다.

index.tsx

import { Provider } from 'react-redux'
import App from './App'
import store from './redux/store'

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById('root'),
)

청원사이트 프로젝트에서 store를 쓰기 위해 store 속성이 들어가있는 Provider 컴포넌트로 App 을 감싸줍니다.

redux > auth > authSlice.ts

import { createSlice } from '@reduxjs/toolkit'

const initialState = {
  isAuthorized: false,
}

export const authSlice = createSlice({
  name: 'auth',
  initialState,
  reducers: {
    setLogin: state => {
      state.isAuthorized = true
    },
    setLogout: state => {
      state.isAuthorized = false
    },
  },
})

export const { setLogin, setLogout } = authSlice.actions

export default authSlice.reducer

createSlice가 필요한 객체의 값들은 다음과 같습니다.

  • initial state
  • slice 이름
  • reducers - 안에 액션에 대한 정의와 그 액션에 따른 처리 방법이 적혀있습니다.

그리고 slice를 생성하면 저희는 안에 정의된 액션 생성자들을 export할 수 있습니다. 이 액션 생성자는 아무데서나 사용 가능합니다.

pages > Login > index.tsx

import React, { FormEvent, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { useDispatch } from 'react-redux'
import { setLogin } from '../../redux/auth/authSlice'
import { checkLoginError } from '../../utils/checkUser'
import { postLogin } from '../../utils/api/postLogin'

const Login = (): JSX.Element => {
  const [user, setUser] = useState<User>({ username: '', password: '' })
  const [responseState, setResponseState] = useState(0)

  const handleChangeUser = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target
    setUser({ ...user, [name]: value })
  }
  const navigate = useNavigate()
  const dispatch = useDispatch()
  const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault()
    try {
      const loginStatus = await postLogin(user)
      setResponseState(loginStatus)

      if (loginStatus < 400) {
        navigate('/')
        dispatch(setLogin())
      }
    } catch (error) {
      console.log(error)
    }
  }
  return (
    // ...
  )
}

export default Login

postLogin (API) 에 대한 설명은 여기서 자세히 다루지 않겠습니다.
로그인 시 필요한 POST API 요청을 서버에게 보낸다는 것만 알고 가면 됩니다.

유저가 인풋창에 적은 정보가 handleChangeUser에 의해 user객체에 담기게 됩니다.
dispatch는 저번 리덕스 세션때 말한 액션을 보내기 위한 함수입니다.
로그인 버튼을 누르면 handleSubmit 함수가 실행되고 postLogin API요청을 보냅니다.

성공적으로 실행했다면 (loginState < 400)
setLogin() 액션을 보냅니다. 여기엔 같이 보내줄 데이터가 없기 때문에 인자엔 아무것도 없습니다.
이제 액션에 대한 어떤 결과가 실행될까요??

다시 authSlice.ts를 가면 setLogin에 대한 처리 방법이 정의돼있는 것을 확인할 수 있습니다.

setLogin: state => {
  state.isAuthorized = true
}

Reference

리덕스 툴킷 공식 페이지