npm
$ npm install redux
$ npm install react-redux
$ npm install redux-persist
$ npm install react-router-dom
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { legacy_createStore as createStore } from 'redux';
import { Provider } from 'react-redux';
import rootReducer from './reducers';
import { persistStore } from 'redux-persist';
import { PersistGate } from 'redux-persist/integration/react';
const store = createStore(rootReducer);
const persistor = persistStore(store);
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>
);
App.js
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Counter from "./components/Counter";
import Login from './components/Login';
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Counter />} />
<Route path="/login" element={<Login />} />
</Routes>
</Router>
);
}
export default App;
components/Counter.js
import { useSelector, useDispatch } from "react-redux";
import { increaseCount, decreaseCount } from "../reducers/counter";
const Counter = () => {
const dispatch = useDispatch();
const { count } = useSelector(state => state.counter);
const increase = () => {
dispatch(increaseCount(count + 1));
};
const decrease = () => {
dispatch(decreaseCount(count - 1));
}
return (
<div>
카운트{count} <br />
<button onClick={increase}>증가</button>
<button onClick={decrease}>감소</button>
</div>
);
};
export default Counter;
components/Login.js
import { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { signIn } from "../reducers/auth";
const Login = () => {
const dispatch = useDispatch();
const navigation = useNavigate();
const auth = useSelector(state => state.auth);
const [formData, setFormData] = useState({ id: "", password: "" });
const { id, password } = formData;
const onChange = (e) => {
const { target: { value, name } } = e;
if (name === "id") setFormData({...formData, id: value});
else if (name === "password") setFormData({...formData, password: value});
};
const onSubmit = (e) => {
e.preventDefault();
dispatch(signIn(formData))
navigation("/login");
}
return (
<>
<form onSubmit={onSubmit}>
<input type="text" name="id" value={id} onChange={onChange} />
<input type="password" name="password" value={password} onChange={onChange} />
<input type="submit" value="저장" />
</form>
{
auth && <div>{auth.id} {auth.password}</div>
}
</>
);
}
export default Login;
reducers/counter.js
export const INCREASE = "INCREASE";
export const DECREASE = "DECREASE";
export const increaseCount = count => ({ type: INCREASE, count });
export const decreaseCount = count => ({ type: DECREASE, count });
const initalState = {
count: 0
};
export const counter = (state = initalState, action) => {
switch(action.type) {
case INCREASE :
return {
...state,
count: action.count
};
case DECREASE :
return {
...state,
count: action.count
}
default:
return state;
}
}
reducers/auth.js
export const AUTH = "SIGNIN";
export const signIn = (state) => ({ type: AUTH, state })
const initState = {
id: "",
password: ""
};
export const auth = (state = initState, action) => {
console.log(action.state);
switch(action.type) {
case AUTH :
return {
...state,
id: action.state.id,
password: action.state.password
}
default :
return state;
}
}
reducers/index.js
import { combineReducers } from "redux";
import { counter } from "./counter";
import { auth } from "./auth";
import { persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
// import storageSession from 'redux-persist/lib/storage/session';
const persistConfig = {
key: "root",
storage: storage
}
const rootReducer = combineReducers({
auth,
counter,
})
export default persistReducer(persistConfig, rootReducer);
storage : 로컬스토리지
storageSession : 세션스토리지
:: 로컬스토리지는 새로고침, 브라우저 재실행해도 데이터가 사라지지 않고, 세션스토리지는 새로고침시에만 데이터가 사라지지 않습니다.