Redux의 흐름을 파악하기 위해,
버튼을 클릭하면 숫자가 증가/감소하는 간단한 앱을 만들어 보자. 👻
src
-actions
-action.js
-reducers
-counter.js
-isLogged.js
-index.js
-App.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")
//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
combineReducers
사용 예를 기록하기 위해 isLogged
라는 reducer
를 하나 더 생성해 주었다.
const isLoggedReducer = (state = false, action) => {
switch (action.type) {
case "SIGN_IN":
return !state
default:
return state
}
}
export default isLoggedReducer
reducer
가 여러개일 경우 combineReducers
사용하여 아래와 같이 하나로 묶어 줄 수있다. counterReducer
와 isLoggedReducer
를 묶어 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 에는 객체를 return 하는 함수를 만들어 준다.
export const increment = (num) => {
return { type: "INCREMENT", payload: num }
}
export const decrement = () => {
return { type: "DECREMENT" }
}
최상위 컴포넌트,
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
이기 때문에 화면에 나타나지 않는다.