Skip to content

Instantly share code, notes, and snippets.

@geovannaotoni
Forked from ANDREHORMAN1994/checklist-redux.md
Last active June 27, 2023 20:04
Show Gist options
  • Save geovannaotoni/5741db62111537dd6e8893ee18bb9bde to your computer and use it in GitHub Desktop.
Save geovannaotoni/5741db62111537dd6e8893ee18bb9bde to your computer and use it in GitHub Desktop.
Checklist do Redux

Checklist do Redux

Antes de começar

  • pensar como será o formato do seu estado global
  • pensar quais actions serão necessárias na sua aplicação

Instalação

  • npx create-react-app my-app-redux;
  • npm install --save redux react-redux;
  • npm install --save @redux-devtools/extension

Criar dentro do diretório src:

  • diretório redux

Criar dentro do diretório redux

  • arquivo store.js ou index.js
  • diretório actions
  • diretório reducers

Criar dentro do diretório actions:

  • arquivo index.js.

Criar dentro do diretório reducers:

  • arquivo index.js.

Criar dentro do arquivo redux/store.js ou redux/index.js:

  • importar o createStore
  • configurar o Redux DevTools
  • importar o rootReducer
  • criar e exportar a store

Exemplo:

import { legacy_createStore as createStore } from 'redux';
import { composeWithDevTools } from '@redux-devtools/extension';
import rootReducer from './reducers';

const store = createStore(rootReducer, composeWithDevTools());

export default store;

Criar dentro do arquivo redux/reducers/index.js:

  • estado inicial
  • criar função reducer com switch retornando apenas a opção default
  • criar rootReducer usando o combineReducers
  • exportar rootReducer

Obs: o estado inicial e a função reducer podem ser criadas em um arquivo separado na pasta redux/reducers/

Exemplo:

import { combineReducers } from 'redux';

const INITIAL_STATE = {};

const exampleReducer = (state = INITIAL_STATE, action) => {
  switch(action.type) {
    default:
    return state;
  }
}

const rootReducer = combineReducers({ exampleReducer })

export default rootReducer;

No arquivo src/index.js:

  • importar a store
  • importar o Provider, para fornecer os estados a todos os componentes encapsulados pelo <App />

Exemplo:

// Na importação
import { Provider } from 'react-redux';
import store from './redux/store';
import { BrowserRouter } from 'react-router-dom';
// No render
 <Provider store={ store } >
   <BrowserRouter>
     <App />
   </BrowserRouter>
 </Provider>

Na pasta actions/index.js:

  • criar e exportar os actionTypes

Exemplo:

// ACTIONS TYPES
export const ADD_EMAIL = 'ADD_EMAIL';
  • criar e export os actions creators necessários

Exemplo:

// ACTIONS CREATORS
export const addEmail = (email) => ({
  type: ADD_EMAIL,
  payload: email,
})

Nos reducers:

  • criar os casos para cada action criada, retornando o devido estado atualizado
const INITIAL_STATE = {
  email: '',
};

const exampleReducer = (state = INITIAL_STATE, action) => {
  switch(action.type) {
    case ADD_EMAIL:
      return {
        ...state,
        email: action.payload
      }
    default:
    return state;
  }
}

Nos componentes que irão ler o estado:

  • criar a função mapStateToProps (é por meio dela que é possivel capturar o estado, substituindo o subscribe)
  • exportar usando o connect
// No import
import { connect } from 'react-redux';

// Acesso ao estado global
const mapStateToProps = (state) => ({
  email: state.email,
});

// No export
export default connect(mapStateToProps)(Component)

Nos componentes que irão modificar o estado:

  • Importar a action creator a ser utilizada
  • exportar usando o connect (serve para conectar o componente ao redux, tendo acesso ao estado global do redux. Além disso, ele deixa o dispatch presente de forma automática nas props)
  • Desconstruir o dispatch via props
  • Utilizar a função dispatch para enviar a action ao reducer
// No import
import { connect } from 'react-redux';
import { addEmail } from '../redux/actions';

// Disparando a action
const handleClick = () => {
  const { dispatch } = this.props;
  dispatch(addEmail('teste@teste.com'));
}
// No export
export default connect()(Component)

Redux-thunk:
A solução padrão para se ter actions assíncronas, recomendada na documentação do Redux, é via uso do pacote redux-thunk.

Instalação

  • npm install redux-thunk;

No arquivo em que a redux store é criada:

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from '/path/to/your/root/reducer';
// ...
// ou composeWithDevTools(applyMiddleware(thunk))
const store = createStore(reducer, applyMiddleware(thunk));
// ...

No arquivo redux/actions/index.js:

Criar as Action Creator's:

export const REQUEST_STARTED = 'REQUEST_STARTED';
export const REQUEST_SUCCESSFUL = 'REQUEST_SUCCESSFUL';
export const REQUEST_FAILED = 'REQUEST_FAILED';

const requestStarted = () => ({
  type: REQUEST_STARTED,
});

const requestSuccessful = (data) => ({
  type: REQUEST_SUCCESSFUL,
  payload: data,
})

const requestFailed = (error) => ({
  type: REQUEST_FAILED,
  payload: error,
});

E a Thunk Action Creator (com then):

// thunk action creator: deve retornar uma função
export function fetchDogImage() {
  return (dispatch, _getState) => {
    dispatch(requestStarted());
    fetch("https://dog.ceo/api/breeds/image/random")
      .then(response => response.json())
      .then(data => dispatch(requestSuccessful(data.message)))
      .catch((error) => dispatch(requestFailed(error)));
  }

ou ainda (com async await)

export function fetchAPI() {
  return async (dispatch) => {
    try {
      dispatch(requestAPI());
      const response = await fetch('https://aws.random.cat/meow');
      const data = await response.json();
      dispatch(getPicture(data));
    } catch (error) {
      console.error(error);
    }
  }
};

Outro Exemplo:

const setPosts = (posts) =>{
	return {
		type: 'SET_POSTS',
    payload: posts
  }
}

const getPosts = () => async (dispatch, getState) => { 
	const response = await consultaApi('https://minha-api.com/posts');
  
  dispatch(setPosts(response.data.posts));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment