Redux 흐름 파악하기

devCecy·2021년 1월 24일
0

React

목록 보기
14/14
post-thumbnail
post-custom-banner

Redux의 흐름을 파악하기 위해,
버튼을 클릭하면 숫자가 증가/감소하는 간단한 앱을 만들어 보자. 👻

src 폴더구조

src
 -actions
 	-action.js
 -reducers 
 	-counter.js
    	-isLogged.js
    	-index.js
 -App.js
 -index.js

index.js

import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
import { createStore } from "redux" //createStore import
import { Provider } from "react-redux" //Provider import
import allReducers from "./reducers/index" //컴바인된 reducer import 

//sotre 생성 
const store = createStore(
  allReducers, // 컴바인된 reducer
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() //redux devTool사용을 위해 import 해줌. 
)

//Provider에 props로 store를 보내주고 최상위 컴포넌트 감싸기
ReactDOM.render(
  <Provider store={store}> 
    <App />
  </Provider>,
  document.getElementById("root")

reducers > counter.js

//reducer는 인자로 state와 action 2개를 받는다 
//초기 state값은 0
const counterReducer = (state = 0, action) => {
  switch (action.type) {
    case "INCREMENT":
      return state + action.payload
    case "DECREMENT":
      return state - 1
    default:
      return state
  }
}

export default counterReducer

reducers > isLogged.js

combineReducers사용 예를 기록하기 위해 isLogged라는 reducer를 하나 더 생성해 주었다.

const isLoggedReducer = (state = false, action) => {
  switch (action.type) {
    case "SIGN_IN":
      return !state
    default:
      return state
  }
}

export default isLoggedReducer

reducers > index.js

reducer가 여러개일 경우 combineReducers사용하여 아래와 같이 하나로 묶어 줄 수있다. counterReducerisLoggedReducer를 묶어 allReducer로 만들었으며, 이것을 index.js에서 생성한 store에 넣어주면된다.

import { combineReducers } from "redux"
import counterReducer from "./counter"
import isLoggedReducer from "./isLogged"

const allReducers = combineReducers({
  counter: counterReducer,
  isLogged: isLoggedReducer,
})

export default allReducers

action.js

action 에는 객체를 return 하는 함수를 만들어 준다.

export const increment = (num) => {
  return { type: "INCREMENT", payload: num }
}

export const decrement = () => {
  return { type: "DECREMENT" }
}

App.js

최상위 컴포넌트,
useSelector는 hook에서 redux의 상태값을 조회할 수 있는 함수이다.
아무 버튼도 누르지 않았다면 counter.js의 초기 state값이 0이기 때문에 <h1>count : {counter}</h1>에서 {counter}에 나타나는 값은 0이 된다.

useDispatch는 action을 연결해 주는 함수로, onClick이벤트 발생시, action.js에서 작성해 둔 increment()decrement()라는 액션 함수를 연결해 주고 있다.

이때, +버튼을 클릭하면 increment()는 10이라는 인자를 받고 있는데, 액션함수는 이것을 payload라는 이름으로 받게 된다.

import React from "react"
import { useSelector, useDispatch } from "react-redux"
import { increment, decrement } from "./actions/action"

function App() {
  const counter = useSelector((state) => state.counter)
  const isLogged = useSelector((state) => state.isLogged)
  const dispatch = useDispatch()

  return (
    <div className="App">
      <h1>count : {counter}</h1>
      <button onClick={() => dispatch(increment(10))}>+</button>
      <button onClick={() => dispatch(decrement())}>-</button>
      {isLogged ? <h3>로그인되어야 볼수 있는 화면입니다</h3> : ""}
    </div>
  )
}

export default App

최종화면

위의 모든 코드 작성이 완료되면, +버튼 클릭시 인자로 10을 보내주었기 때문에 10씩 증가하게되고, -버튼을 클릭하면 1씩 감소하는 앱이 만들어진다.
isLogged는 초기 state값이 false이기 때문에 화면에 나타나지 않는다.

profile
🌈그림으로 기록하는 개발자🌈
post-custom-banner

0개의 댓글