21
loading...
This website collects cookies to deliver better user experience
npm install -g create-react-app
create-react-app redux-tutorial
cd redux-tutorial
npm install --save react-redux @reduxjs/toolkit
import { configureStore } from '@reduxjs/toolkit'
import { combineReducers } from 'redux'
const reducer = combineReducers({
// here we will be adding reducers
})
const store = configureStore({
reducer,
})
export default store;
...
import { Provider } from 'react-redux'
import store from './store'
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
import { createSlice } from '@reduxjs/toolkit'
// Slice
const slice = createSlice({
name: 'user',
initialState: {
user: null,
},
reducers: {
loginSuccess: (state, action) => {
state.user = action.payload;
},
logoutSuccess: (state, action) => {
state.user = null;
},
},
});
export default slice.reducer
// Actions
const { loginSuccess, logoutSuccess } = slice.actions
export const login = ({ username, password }) => async dispatch => {
try {
// const res = await api.post('/api/auth/login/', { username, password })
dispatch(loginSuccess({username}));
} catch (e) {
return console.error(e.message);
}
}
export const logout = () => async dispatch => {
try {
// const res = await api.post('/api/auth/logout/')
return dispatch(logoutSuccess())
} catch (e) {
return console.error(e.message);
}
}
...
import user from './user'
const reducer = combineReducers({
user,
})
npm install --save formik
...
import {useDispatch, useSelector} from 'react-redux'
import {Field, Form, Formik} from 'formik'
import {login, logout} from './store/user'
function App() {
const dispatch = useDispatch()
const { user } = useSelector(state => state.user)
if (user) {
return (
<div>
Hi, {user.username}!
<button onClick={() => dispatch(logout())}>Logout</button>
</div>
)
}
return (
<div>
<Formik
initialValues={{ username: '', password: '' }}
onSubmit={(values) => { dispatch(login(values)) }}
>
{({ isSubmitting }) => (
<Form>
<Field type="text" name="username" />
<Field type="password" name="password" />
<button type="submit" disabled={isSubmitting}>Login</button>
</Form>
)}
</Formik>
</div>
);
}
+const initialUser = localStorage.getItem('user')
+ ? JSON.parse(localStorage.getItem('user'))
+ : null
+
const slice = createSlice({
name: 'user',
initialState: {
- user: null,
+ user: initialUser,
},
reducers: {
loginSuccess: (state, action) => {
state.user = action.payload;
+ localStorage.setItem('user', JSON.stringify(action.payload))
},
logoutSuccess: (state, action) => {
state.user = null;
+ localStorage.removeItem('user')
},
},
});
const api = axios.create({
baseURL: '/',
headers: {
'Content-Type': 'application/json'
},
})
api.interceptors.request.use(
config => {
const token = localStorage.getItem('token')
if (token) {
config.headers['Authorization'] = `Token ${token}`
}
return config
},
error => Promise.reject(error)
)
export default api
if (user) {
return (
<Redirect to={'/home'} />
)
}