Criando Reducers e consumindo dentro de componentes

Criando Reducers e consumindo dentro de componentes

Na lição passada, você aprendeu a instalar e configurar a biblioteca do Redux.

Hoje nós iremos adicionar um pouco mais de lógica dentro daquela pastinha (redux) e criar então os nossos reducers 😊

Criando seu projeto de testes

Antes de começarmos, vamos criar um novo projeto em ReactJS dedicado a esta lição. No meu caso criei um novo projeto chamado de reducers-com-redux:  

npx create-react-app reducers-com-redux

Não se esqueça de instalar também as bibliotecas necessárias:

npm install redux react-redux @reduxjs/toolkit

Após isso, eu vou aproveitar aquela pasta do src que desenvolvemos no projeto anterior. Vou fazer isso pra gente ganhar um pouco de tempo no desenvolvimento dessa lição 😉

Criando nossos Slices

Supondo que nós queremos controlar o estado do usuário (nome, email, site...) em toda a nossa aplicação feita com ReactJS junto ao Redux.

Para isso, nós vamos precisar criar o nosso primeiro reducer chamado de User.

Sendo assim, você pode criar uma nova pasta chamada de user dentro da pasta redux da seguinte forma:

Dentro da pasta user, vamos criar o nosso primeiro arquivo chamado de slice.js.

Alí dentro vamos inserir a seguinte lógica.

redux > user > slice.js

import { createSlice } from '@reduxjs/toolkit';

const InitialState = {
 user: {
 id: 1,
 name: 'Micilini Roll',
 site: 'https://micilini.com/'
 }
}

export const userSlice = createSlice({
 name: 'user',
 initialState: InitialState,//podemos passar de forma direta o initialState sem atribuir a uma variável
 reducers: {

 }
});

export default userSlice.reducer;

Vamos as explicações 🙂

createSlice é uma função fornecida pelo Redux Toolkit que permite definir um slice do estado Redux. Um slice é uma parte do estado da aplicação que pode conter seu próprio estado e seus próprios reducers.

InitialState é um objeto JavaScript que define o estado inicial do slice user. Aqui, há um objeto user com algumas informações fictícias como id, name e site.

createSlice cria um slice do estado Redux. Ele recebe um objeto como parâmetro com as seguintes propriedades:

  • name: é o nome do slice, que futuramente iremos usá-lo para identificar e consumir o estado global do redux.
  • initialState: é o estado inicial do slice.
  • reducers: são objetos que contém funções puras responsáveis por realizar alterações dos slices.

userSlice.reducer é o reducer gerado automaticamente pelo createSlice, ele contém a lógica para atualizar o estado user com base nas ações definidas nos reducers (que ainda não foram definidos).

Importando nosso Slice no root-reducer

Após isso, precisamos fazer uma chamada do slice que acabamos de criar em nosso agrupador de reducers.

redux > root-reducer.js:

import { combineReducers } from "redux";
import userSlice from "./user/slice";

export default combineReducers({
 user: userSlice
});

(Basicamente é só remover os comentários que fizemos no projeto anterior 😆)

Observação: o userSlice não deve estar dentro de chaves ({}).

Após isso, nosso slice já está pronto para consumo em toda a nossa aplicação 🥳

Criando o componente <Perfil />

Para testar o redux, vamos começar criando um novo componente chamado de Perfil dentro da pasta components.

Perfil > index.jsx:

const Perfil = () => {
 return(
 <>
 <h1>Meu Perfil</h1>
 <br />
 <p>Id: ...</p>
 <p>Nome: ...</p>
 <p>Site: ...</p>
 </>
 );
}

export default Perfil;

Como podemos ver ele é um componente bem simples que mostra apenas as informações de um determinado usuário.

Não se esqueça de adicionar esse componente dentro do App.js:

import Perfil from "./components/Perfil";

export default function App() {
 return (
 <>
 <Perfil />
 </>
 );
}

Chamando o slice dentro de <Perfil />

Para chamarmos o slice em conjunto com os reducers dentro do componente Perfil, podemos fazer isso da seguinte forma:

Perfil > index.jsx:  

import { useSelector } from "react-redux";

const Perfil = () => {
 const { user } = useSelector((rootReducer) => rootReducer.user);//pegamos o estado do usuário declarado dentro do rootReducer

 return(
 <>
 <h1>Meu Perfil</h1>
 <p>Id: {user.id}</p>
 <p>Nome: {user.name}</p>
 <p>Site: {user.site}</p>
 </>
 );
}

export default Perfil;

No caso do comando acima estamos importando o useSelector da biblioteca do 'react-redux' e puxando o user por meio do rootReducer.

O retorno disso será um objeto contendo todas aquelas informações que declaramos dentro de initialState.user:

const InitialState = {
 user: {
 id: 1,
 name: 'Micilini Roll',
 site: 'https://micilini.com/'
 }
}

Tanto que só precisamos acessar nossas essas chaves dentro do JSX:

return(
 <>
 <h1>Meu Perfil</h1>
 <p>Id: {user.id}</p>
 <p>Nome: {user.name}</p>
 <p>Site: {user.site}</p>
 </>
);

Veja como ficou o resultado final:

Eu posso começar com o initialState setado como nulo? Sim, sem nenhum problema, observe:

const InitialState = {
 user: null
}

Eu posso ter outras chaves além de user? Sim, observe como é feito:

const InitialState = {
 user: 'Micilini',
 status: true
}

...

const { user, status } = useSelector((rootReducer) => rootReducer.user);

"E agora como eu seto as informações existentes dentro do InitialState?".

Bem, é um assunto para a próxima lição 😝

Arquivos da lição

Os arquivos dessa lição podem ser encontrados neste repositório do GitHub.

Conclusão

Nesta lição você aprendeu a criar e consumir seu primeiro reducer (por meio do arquivo slice.js).

Na próxima lição aprenderemos a setar informações de dentro do nosso componente para nosso reducer 😄