Autenticação
Configurações do Redux
Instalações
Dependências iniciais do Redux:
$ yarn add redux redux-saga react-redux reactotron-redux reactotron-redux-saga immer
Arquivo src/store/modules/auth/reducer.js
const INITIAL_STATE = {};export default function auth(state = INITIAL_STATE, action) {switch (action.type) {default:return state;}}
Arquivo src/store/modules/auth/sagas.js
import { all } from 'redux-saga/effects';export default all([]);
Arquivo src/store/modules/rootReducer.js
import { combineReducers } from 'redux';import auth from './auth/reducer';export default combineReducers({ auth });
Arquivo src/store/modules/rootSaga.js
import { all } from 'redux-saga/effects';import auth from './auth/sagas';export default function* rootSaga() {return yield all([auth]);}
Arquivo src/store/index.js
import createSagaMiddleware from 'redux-saga';import createStore from './createStore';import rootReducer from './modules/rootReducer';import rootSaga from './modules/rootSaga';const sagaMiddleware = createSagaMiddleware();const middlewares = [sagaMiddleware];const store = createStore(rootReducer, middlewares);sagaMiddleware.run(rootSaga);export default store;
Arquivo src/store/createStore.js
import { createStore } from 'redux';export default (reducers, middlewares) => {return createStore(reducers, middlewares);};
Configurações
Configurações do Reactotron
Arquivo src/config/ReactotronConfig.js
*
Configurações do Reactotron
import Reactotron from 'reactotron-react-js';import { reactotronRedux } from 'reactotron-redux';import reactotronSaga from 'reactotron-redux-saga';if (process.env.NODE_ENV === 'development') {const tron = Reactotron.configure().use(reactotronRedux()).use(reactotronSaga()).connect();tron.clear();console.tron = tron;}
Arquivo src/store/index.js
Alteração no sagaMiddleware e criação do sagaMonitor:
// ...const sagaMonitor =process.env.NODE_ENV === 'development'? console.tron.createSagaMonitor(): null;const sagaMiddleware = createSagaMiddleware({ sagaMonitor });// ...
Arquivo src/store/createStore.js
Criação da variável enhancer para utilização do Reactotron.
import { createStore, compose, applyMiddleware } from 'redux';export default (reducers, middlewares) => {const enhancer =process.env.NODE_ENV === 'development'? compose(console.tron.createEnhancer(), applyMiddleware(...middlewares)): applyMiddleware(...middlewares);return createStore(reducers, enhancer);};
Arquivo src/App.js
Inserção do Provider entre todos os componentes e do método store após as configurações do Reactotron:
// import React from 'react';import { Provider } from 'react-redux';// import { Router } from 'react-router-dom';import './config/ReactotronConfig';// import Routes from './routes';// import history from './services/history';import store from './store';// import GlobalStyle from './styles/global';function App() {return (<Provider store={store}>{/*<Router history={history}><Routes /><GlobalStyle /></Router>*/}</Provider>);}export default App;
Autenticação do usuário
Criação das actions de Autenticação
Arquivo src/store/modules/auth/actions.js
export function signInRequest(email, password) {return {type: '@auth/SIGN_IN_REQUEST',payload: { email, password },};}export function signInSuccess(token, user) {return {type: '@auth/SIGN_IN_SUCCESS',payload: { token, user },};}export function signFailure() {return {type: '@auth/SIGN_FAILURE',};}
Instalar o Axios com o comando $ yarn add axios
e criar o arquivo src/services/api.js
:
import axios from 'axios';const api = axios.create({baseURL: 'http://localhost:3333',});export default api;
Implementação da tratativa de login com o Redux Saga
Arquivo src/store/modules/auth/sagas.js
import { takeLatest, call, put, all } from 'redux-saga/effects';import { signInSuccess } from './actions';import api from '~/services/api';import history from '~/services/history';export function* signIn({ payload }) {const { email, password } = payload;const response = yield call(api.post, 'sessions', {email,password,});const { token, user } = response.data;if (!user.provider) {console.tron.error('Usuário não é prestador');}yield put(signInSuccess(token, user));history.push('/dashboard');}export default all([takeLatest('@auth/SIGN_IN_REQUEST', signIn)]);
Configurações da tela de Login
Arquivo src/pages/SignIn/index.js
Importação do useDispatch e da Action de SignIn criada anteriormente:
import { useDispatch } from 'react-redux';import { signInRequest } from '~/store/modules/auth/actions';
Criação da função de login dentro do componente (function SignIn() {...}
):
const dispatch = useDispatch();function handleSubmit({ email, password }) {dispatch(signInRequest(email, password));}
Lidando com o token para redirecionar para a aplicação
Arquivo src/store/modules/auth/reducer.js
import produce from 'immer';const INITIAL_STATE = {token: null,signed: false,loading: false,};export default function auth(state = INITIAL_STATE, action) {switch (action.type) {case '@auth/SIGN_IN_SUCCESS':return produce(state, draft => {draft.token = action.payload.token;draft.signed = true;});default:return state;}}
Alterações no arquivo de rotas
Arquivo src/routes/Route.js
Importação do arquivo store:
import store from '~/store'
Alteração da variável signed
:
const { signed } = store.getState().auth;
Armazenando os dados do usuário
Criação dos arquivos referentes ao Redux para o user:
- src
- store
- modules
- user
- actions.js
- reducer.js
- sagas.js
- user
- modules
- store
Arquivo src/store/modules/user/reducer.js
import produce from 'immer';const INITIAL_STATE = {profile: null,};export default function user(state = INITIAL_STATE, action) {switch (action.type) {case '@auth/SIGN_IN_SUCCESS':return produce(state, draft => {draft.profile = action.payload.user;});default:return state;}}
Arquivo src/store/modules/user/sagas.js
import { all } from 'redux-saga/effects';export default all([]);
Importar o user
no rootSaga e rootReducer