버전에 맞춰서 강의와 다른 코드가 있습니다.
강의와 별개로 추가한 내용입니다.
결과 화면
redux-persist 패키지를 사용해서 데이터를 로컬 스토리지에 저장했다.
yarn add redux-persist 또는 npm install redux-persist
파일 구조
- src/index.js
1. persistStore, PersistGate를 import 시킨다.
2. persistStore(store)를 만든다.
3. PersistGate 태그로 App 컴포넌트를 감싼다.
import React from 'react'
import ReactDOM from 'react-dom/client'
import { Provider } from 'react-redux'
import { persistStore } from 'redux-persist';
import { PersistGate } from 'redux-persist/integration/react';
import store from './store/store'
import App from './App'
const root = ReactDOM.createRoot(document.getElementById('root'))
const persistor = persistStore(store)
root.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App/>
</PersistGate>
</Provider>
)
- src/store/rootReducer.js
1. store 디렉터리에 rootReducer.js 파일을 만든다.
2. combineReducers()에 기존에 만든 reducer를 작성한다. (toDos 이외에 리듀서가 여러 개라면 쉼표로 추가해 작성한다.)
import { combineReducers } from 'redux'
import toDos from './toDoReducer'
const rootReducer = combineReducers({
toDos
})
export default rootReducer
- src/store/store.js
1. store와 reducer를 나눠서 작성한다. (store 관련 코드만 남긴다.)
2. persistReducer를 import 시키고, persistReducer()에 rootReducer를 파라미터로 가지고 온다.
3. persistConfig 변수를 만들고, configureStore()에 리듀서를 작성한다.
import { configureStore } from '@reduxjs/toolkit'
import { persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import rootReducer from './rootReducer'
const persistConfig = {
key: 'root',
storage
}
const reducer = persistReducer(persistConfig, rootReducer)
const store = configureStore({
reducer
})
export default store
- src/store/toDoReducer.js
1. store와 reducer를 나눠서 작성한다. (reducer관련 코드만 남긴다. 파일명이 헷갈릴 수 있으니 리네이밍한다.)
import { createSlice } from '@reduxjs/toolkit'
const todoSlice = createSlice({
name: 'reducerToDo',
initialState: {
toDoList: []
},
reducers: {
addToDo: (state, action) => {
state.toDoList.unshift({ id: Date.now(), text: action.payload })
},
deleteToDo: (state, action) => {
state.toDoList = state.toDoList.filter(list => list.id !== action.payload)
}
}
})
export const { addToDo, deleteToDo } = todoSlice.actions
export default todoSlice.reducer
- src/routes/Home.js
1. useSelector()로 state를 가지고 올 때, 로컬 스토리지에 있는 데이터(state.toDos.toDoList)를 가지고 온다.
import React, { useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { addToDo } from '../store/toDoReducer'
import ToDo from '../components/ToDo'
import './home.scss'
function Home() {
// ** Hooks
const dispatch = useDispatch()
// ** States
const [text, setText] = useState('')
// ** Redux States
const toDos = useSelector(state => state.toDos.toDoList)
function onChange(e) {
setText(e.target.value)
}
function onSubmit(e) {
e.preventDefault()
dispatch(addToDo(text))
setText('')
}
return (
<>
<div className="layout home">
<h1>To Do List</h1>
<form onSubmit={onSubmit}>
<input type="text" value={text} onChange={onChange} placeholder="What is your to do?"/>
<button>Add</button>
</form>
<ul>
{
toDos.map((toDo, index) => {
return (
<ToDo id={toDo.id} text={toDo.text} key={index}/>
)
})
}
</ul>
</div>
</>
)
}
export default Home
자세한 소스코드는 아래 깃 레포지토리를 참고한다.