Logo

dev-resources.site

for different kinds of informations.

Por que eu não uso bibliotecas de gerenciamento de estado no React

Published at
12/14/2024
Categories
react
webdev
redux
ptbr
Author
oieduardorabelo
Categories
4 categories in total
react
open
webdev
open
redux
open
ptbr
open
Author
15 person written this
oieduardorabelo
open
Por que eu não uso bibliotecas de gerenciamento de estado no React

Original source in English by Fabrizio Beccaceci
Why i no longer use a React state management library
https://medium.com/@ipla/why-i-no-longer-use-a-react-state-management-library-7bdffae54600

Índice

  • O que é uma Biblioteca de Gerenciamento de Estado Global?
  • Como o Redux Toolkit Resolve o Estado Global
  • As Duas Faces do Estado Global
  • A Abordagem Enxuta para Estado Global
    • Para Estado do Servidor use TanStack Query
    • Para Estado Compartilhado use Observables
  • Por que não usar React Context?
  • Conclusão

Quando comecei a aprender React anos atrs, havia duas coisas que voc precisava saber para se considerar um desenvolvedor React: TypeScript e Redux.

Hoje em dia, as coisas mudaram. Se voc est aprendendo React agora e se depara com o conceito de gerenciamento de estado, vai se sentir sobrecarregado com uma infinidade de bibliotecas: Redux, Redux Toolkit, MobX, Jotai, Zustand e a lista continua.

Mas antes de nos aprofundarmos, vamos responder pergunta bsica:

O que uma Biblioteca de Gerenciamento de Estado Global?

Mesmo se voc for relativamente novo no React, provavelmente sabe o que o termo estado. Voc cria um com o hook useState, e quando voc o atualiza, seu aplicativo renderiza novamente para refletir as mudanas.

No entanto, as coisas ficam complicadas quando voc precisa compartilhar alguma informao entre vrias partes no conectadas do seu aplicativo React.

Isso o que frequentemente chamamos de estado global , e o problema que as bibliotecas de gerenciamento de estado tentam resolver: como tornar o estado compartilhado acessvel a qualquer componente.

Vamos ver como o Redux Toolkit lida com isso.

Como o Redux Toolkit Resolve o Estado Global

Primeiro, voc cria uma store :

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

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

// Inferindo os tipos de RootState e AppDispatch usando a store
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
Enter fullscreen mode Exit fullscreen mode

Este o local central onde seu estado global ir existir. Em seguida, voc envolve seu aplicativo com um provider para tornar a store acessvel a todos os componentes:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import { store } from './app/store';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode

Agora, voc precisa definir os slices , que so partes individuais do seu estado global. Por exemplo:

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

interface CounterState {
  value: number;
}
const initialState: CounterState = { value: 0 };
export const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => { state.value += 1; },
    decrement: (state) => { state.value -= 1; },
    incrementByAmount: (state, action) => {
      state.value += action.payload;
    },
  },
});
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
Enter fullscreen mode Exit fullscreen mode

Por fim, voc conecta este slicestore:

import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './features/counter/counterSlice';

export const store = configureStore({
  reducer: { counter: counterReducer },
});
Enter fullscreen mode Exit fullscreen mode

Neste ponto, voc pode usar seu estado global nos componentes da seguinte forma:

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './counterSlice';

export function Counter() {
  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();
  return (
    <div>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <span>{count}</span>
      <button onClick={() => dispatch(decrement())}>Decrement</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Embora o Redux Toolkit simplifique significativamente o Redux, ainda tem muito cdigo boilerplate para o que geralmente uma necessidade simples. E nem sequer falamos sobre aes assncronas como requisies ao servidor!

Alm disso, muitos iniciantes caem na armadilha de colocar todo o seu estado no Redux, levando a stores globais infladas que so mais difceis de gerenciar.

As Duas Faces do Estado Global

Quando voc para pra pensar, a maioria do "estado global" se enquadra em duas categorias:

  1. Estado do Servidor : Dados obtidos de um servidor, como uma lista de clientes em um aplicativo CRM.

  2. Estado da UI Compartilhado : Pequenos pedaos de dados necessrios em vrios lugares, como o usurio atualmente logado.

Vamos abordar cada um deles separadamente.

A Abordagem Enxuta para Estado Global

Com ferramentas modernas, voc pode lidar com estado global sem uma biblioteca dedicada de gerenciamento de estado:

1. Para Estado do Servidor use TanStack Query

TanStack Query (anteriormente React Query) feito especificamente para gerenciar estado do servidor. Ele lida com cache, recarregamento, dados obsoletos e muito mais, tudo pronto para uso, e voc definitivamente deveria usar isso porque voc realmente no vai querer reimplementar tudo isso do zero. Por exemplo, buscar uma lista de clientes to simples quanto:

import { useQuery } from '@tanstack/react-query';

function Customers() {
  const { data, error, isLoading } = useQuery(['customers'], fetchCustomers);
  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
  return <ul>{data.map((customer) => <li key={customer.id}>{customer.name}</li>)}</ul>;
}
Enter fullscreen mode Exit fullscreen mode

O TanStack Query elimina a necessidade de gerenciar manualmente o estado do servidor e, como o estado que voc busca armazenado em cache, voc pode us-lo exatamente da mesma maneira em todos os componentes e ele ser buscado apenas uma vez.

2. Para Estado Compartilhado use Observables

Para estados menores e especficos do aplicativo, como o usurio logado, eu uso uma implementao leve do padro Observable :

export class Observable<T> {
  private _value: T;
  private subscribers = new Set<(value: T) => void>();

  constructor(initialValue: T) {
      this._value = initialValue;
    }
    get value() {
      return this._value;
    }
    set value(newValue: T) {
      this._value = newValue;
      this.notify();
    }
    subscribe(callback: (value: T) => void) {
      this.subscribers.add(callback);
      callback(this._value);
      return { unsubscribe: () => this.subscribers.delete(callback) };
    }
    private notify() {
      this.subscribers.forEach((callback) => callback(this._value));
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Com isso, voc pode conectar Observables ao React usando useSyncExternalStore:

import { useSyncExternalStore } from 'react';

export function useObservable<T>(observable: Observable<T>) {
  return useSyncExternalStore(
    (callback) => observable.subscribe(callback).unsubscribe,
    () => observable.value
  );
}
Enter fullscreen mode Exit fullscreen mode

Agora, voc pode criar e usar observables desta forma:

const loggedUser = new Observable<User>(user);

loggedUser.value // Para acessar o valor dentro do Observable fora do React

loggedUser.value = someOtherUser // Para definir o valor, tanto fora quanto dentro do React
Enter fullscreen mode Exit fullscreen mode

Dentro de um componente React:

const user = useObservable(loggedUser);
Enter fullscreen mode Exit fullscreen mode

Por que no usar React Context?

Embora o React Context funcione em alguns casos, ele tem desvantagens:

  1. Escopo Limitado : Voc no pode acessar o Context fora dos componentes React.

  2. Problemas de Performance : Context dispara uma nova renderizao para todos os componentes abaixo dele, at mesmo para os componentes que no usem o valor atualizado.

Usando Observables evitamos ambos problemas!

Concluso

Gerenciamento de estado global no precisa ser complicado. Combinando TanStack Query e um padro Observable leve, voc pode simplificar seu aplicativo evitando as armadilhas das bibliotecas tradicionais de gerenciamento de estado.

Entre em contato comigo se quiser discutir sobre React, React Native, Nextjs

Bom desenvolvimento! 🎉

redux Article's
30 articles in total
Favicon
Redux Middleware সম্পর্কে বিস্তারিত আলোচনা
Favicon
Comprehensive Redux Toolkit Notes for React Developers
Favicon
🚀 Learning Through Experience: A Tale of NgRx Effects
Favicon
Why Use Redux in React? Complete Guide in Bangla
Favicon
State Management in React 2025: Exploring Modern Solutions
Favicon
[Boost]
Favicon
TypeScript + React Redux: Pro Tips for Type-Safe and Scalable Apps
Favicon
State Management in React: Redux vs. Context API vs. Recoil
Favicon
Redux com React
Favicon
Manual Setup (Custom Webpack/Babel configuration) with react (i am not able running it )
Favicon
TanStack query or RTK query.
Favicon
🚀 React Best Practices for Scalable Frontends: Part 2 – State Management
Favicon
Redux Toolkit - createAsyncThunk()
Favicon
Bootcamping 02: Named exports and default exports - does it really matter?
Favicon
State Management with Redux Toolkit: A Complete Guide
Favicon
Boost Your Application's Performance with Redux RTK Query 🚀
Favicon
Mastering State Machines with XState in React
Favicon
Mastering Redux Basics: A Complete Guide to State Management in React
Favicon
Mastering Redux Toolkit: Simplify State Management in Your React App
Favicon
Redux Made Simple: Managing State Like a Pro
Favicon
I have working on product customization
Favicon
Context, Redux or Composition?
Favicon
Learn Redux Toolkit - React (TypeScript)
Favicon
Por que eu não uso bibliotecas de gerenciamento de estado no React
Favicon
The Role of State Management in React: A Guide to Redux, Context API, and More
Favicon
Creating Theme Systems in React with SCSS and Redux
Favicon
Managing Data with Redux: Storing Content and IDs in Slices
Favicon
🚀 Creating a Feature-Rich Redux Store with Redux Toolkit and TypeScript
Favicon
Redux vs Zustand: A Comprehensive Comparison
Favicon
Advanced Redux

Featured ones: