DEV Community

Aldcejam
Aldcejam

Posted on

1

POR QUE e COMO USAR o Redux??

Redux com Toolkit no ReactJS/NextJS

Quer aprender apenas analisando um código?

Vá ao repositório: https://github.com/aldcejam/Tutorial_Redux-toolkit

O README do projeto diz quais os arquivos necessários para que o Redux funcione
Os commits do projeto seguem a sequência deste tutorial pós instalação

Os porquês:

  1. Organização do estado: O Redux ajuda a manter todas as informações importantes do seu aplicativo organizadas em um só lugar, facilitando o controle e a compreensão.
  2. Fluxo de dados controlado: Com o Redux, você tem um fluxo de dados bem definido, o que torna mais fácil entender como as coisas funcionam e evita problemas inesperados.
  3. Escalabilidade: Se o seu aplicativo está ficando grande e complexo, o Redux oferece uma maneira de gerenciar tudo de forma mais estruturada, facilitando a manutenção e o desenvolvimento contínuo.
  4. Compatibilidade com outras bibliotecas: O Redux é amplamente utilizado em projetos JavaScript e funciona bem com várias bibliotecas e frameworks populares, como React, Angular e Vue.js.
  5. Ferramentas para desenvolvedores: O Redux oferece ferramentas que ajudam no desenvolvimento, depuração e monitoramento do estado do aplicativo, tornando o processo mais fácil e eficiente.

ADENDO: Não é preciso utilizar o Redux para gerenciar todos os estados globais da sua aplicação. Se você tiver um caso simples, como configurar o tema do seu aplicativo, recomendo usar o Context do React.

Como usar:

Etapa 1: Instalação

yarn:

yarn add react-redux @reduxjs/toolkit
Enter fullscreen mode Exit fullscreen mode

npm

npm install react-redux @reduxjs/toolkit
Enter fullscreen mode Exit fullscreen mode

Etapa 2: Configurações:

Crie uma pasta para conter os arquivos hook.ts e o store.ts do Redux

|-- src
    |-- redux.config
        |-- hook.ts
        |-- store.ts
Enter fullscreen mode Exit fullscreen mode

Arquivo hook.ts

Este arquivo será responsável pela tipagem dos estados do Redux.

import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'

export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
Enter fullscreen mode Exit fullscreen mode

Arquivo store.ts

Este arquivo será responsável por centralizar os estados Redux.
Neste arquivo você só precisa entender que cada item em reducer é um Estado Redux, ou seja, cada novo estado redux que criar, o adicione no objeto reducer.

import { configureStore,ThunkAction,Action } from '@reduxjs/toolkit' 
/* import EstadoRedux from "caminho" */

export const Store = configureStore({
  reducer: {
    /* NomeDoEstado: EstadoRedux, */
  },
});

export type AppDispatch = typeof Store.dispatch;
export type RootState = ReturnType<typeof Store.getState>;
export type AppThunk<ReturnType = void> = ThunkAction<
  ReturnType,
  RootState,
  unknown,
  Action<string>
>;
Enter fullscreen mode Exit fullscreen mode

Agora vamos configurar o provider para que todos os nossos componentes e páginas possam acessar os estados do Redux.

caso não esteja utilizando o diretório app com layouts do NextJS
versão 13+, apenas coloque o provider no arquivo _app.ts.

o layout pai de todos ficará assim:

"use client"
import { Provider } from 'react-redux'
import { Store } from '@/redux.config/store'
import './globals.css' 


export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="pt-br">
      <Provider store={Store}>
        <body>{children}</body>
      </Provider>
    </html>
  )
}

Enter fullscreen mode Exit fullscreen mode

Etapa 3: Criar estado redux

O nome do estado será "ShoppingCartData" e terá dois estados, um de string ID e outro de objeto com itens de compra e sua quantidade.

{
   id: string
   itens: {
      carne: string
      arroz: string
   }
}
Enter fullscreen mode Exit fullscreen mode

Siga estas etapas para se manter organizado:

  1. Vamos criar a pasta @core em src para centralizar os estados
  2. Vamos criar uma pasta com o nome do nosso estado
  3. Agora vamos criar um arquivo ShoppingCartData.ts e ShoppingCartData.d.ts para a tipagem
|-- src
    |-- @core
        |-- ShoppingCartData
            |-- ShoppingCartData.ts
            |-- IShoppingCartData.d.ts
Enter fullscreen mode Exit fullscreen mode

no arquivo ShoppingCartData.ts podemos fazer o seguinte código inicial padrão:

import { RootState } from "@/redux.config/store";
import { createSlice, PayloadAction } from "@reduxjs/toolkit";

const initialState = {

}

export const ShoppingCartDataSlice = createSlice({
    name: "ShoppingCartData",
    initialState,
    reducers: {
    }
})

export const { } = ShoppingCartDataSlice.actions

export const ShoppingCartDataStates = (state: RootState) => state.ShoppingCartData

export default ShoppingCartDataSlice.reducer
Enter fullscreen mode Exit fullscreen mode

O objeto InitialStates é o responsável por ter todos os estados deste Redux
O objeto reducers será o responsável por ter todos os setState dos estados em InitialStates

Agora para fazer toda tipagem para o arquivo ShoppingCartData.ts vamos usar o arquivo IShoppingCartData.d.ts. Dado os estados previamente previstos temos a seguinte tipagem:

type IDProps = string
type ShoppingCartItemsProps = {
    [itemName: string]: string;
}

interface IShoppingCartDataProps {
    ID: IDProps;
    shoppingCartItems: ShoppingCartItemsProps;
}

export { IShoppingCartDataProps, IDProps, ShoppingCartItemsProps}
Enter fullscreen mode Exit fullscreen mode

A tipagem dos itens de IShoppingCartDataProps não são atoa, brevemente você entenderá o motivo.

Agora, com a tipagem estabelecida podemos adicionar os estados de initialStates e os reducers no nosso arquivo ShoppingCartData.ts

import { RootState } from "@/redux.config/store";
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { IDProps, IShoppingCartDataProps, ShoppingCartItemsProps } from "./IShoppingCartData"

const initialState: IShoppingCartDataProps = {
    ID: "" as IDProps,
    shoppingCartItems: {} as ShoppingCartItemsProps
}

export const ShoppingCartDataSlice = createSlice({
    name: "ShoppingCartData",
    initialState,
    reducers: {
        setID: (state, action: PayloadAction<IDProps>) => {
            state.ID = action.payload
        },
        setShoppingCartItems: (state, action: PayloadAction<ShoppingCartItemsProps>) => {
            state.shoppingCartItems = action.payload
        }
    }
})

export const {
    setID,
    setShoppingCartItems

} = ShoppingCartDataSlice.actions

export const ShoppingCartDataStates = (state: RootState) => state.ShoppingCartData

export default ShoppingCartDataSlice.reducer
Enter fullscreen mode Exit fullscreen mode

Perceba as seguintes etapas
etapa 1: importação das tipagens do arquivo ShoppingCartData.d.ts.
etapa 2: atribuição da tipagem "IShoppingCartDataProps" em InitialStates.
etapa 3: implementação de valores iniciais para os estados de InitialStates (agora obrigatórios devido a tipagem).
etapa 4: criação dos reducers para cada item de InitialStates. Perceba que tipamos o valor a ser recebido na função set quando colocamos "action: PayloadAction< IDProps>", logo, o state a ser passado para o setID terá que ser um valor do tipo IDProps.
etapa 5: para finalizar exportamos os Set do reducers

para finalizar a etapa 3 podemos importar nosso ShoppingCartData para o store.ts. O arquivo ficará assim:
store.ts:

import ShoppingCartData from '@/@core/ShoppingCartData/ShoppingCartData';
import { configureStore, ThunkAction, Action } from '@reduxjs/toolkit'


export const Store = configureStore({
    reducer: {
        ShoppingCartData,
    },
});

export type AppDispatch = typeof Store.dispatch;
export type RootState = ReturnType<typeof Store.getState>;
export type AppThunk<ReturnType = void> = ThunkAction<
    ReturnType,
    RootState,
    unknown,
    Action<string>
>;
Enter fullscreen mode Exit fullscreen mode

O ShoppingCartData importado é o export default do arquivo ShoppingCartData.ts

Etapa 4: Como MODIFICAR e CONSUMIR os estados

Consumir:

"use client"
import { ShoppingCartDataStates } from '@/@core/ShoppingCartData/ShoppingCartData'
import { useAppSelector } from '@/redux.config/hook'

const id = useAppSelector(ShoppingCartDataStates).ID
const shoppingCartItems = useAppSelector(ShoppingCartDataStates).shoppingCartItems
Enter fullscreen mode Exit fullscreen mode

Modificar:

"use client"
import { setID, setShoppingCartItems } from '@/@core/ShoppingCartData/ShoppingCartData'
import { useAppDispatch } from '@/redux.config/hook'

const dispatch = useAppDispatch();
const modificarID = ()=> dispatch(setID("999"))
const modificarShoppingCartItems = () => dispatch(setShoppingCartItems({
    carne: "2kg",
    arroz: "1kg"
}))
Enter fullscreen mode Exit fullscreen mode

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay