A API Context integrada do React é perfeita para compartilhamento de estado. Descubra como usá-lo com a versão mais recente do Next.js.
Next.js oferece várias abordagens para gerenciamento de estado. Embora alguns desses métodos exijam a instalação de novas bibliotecas, a API Context do React está integrada, portanto é uma ótima maneira de reduzir dependências externas.
Com o React Context, você pode passar dados perfeitamente por diferentes partes de sua árvore de componentes, eliminando o incômodo de perfuração de suporte. Isto é especialmente útil para gerenciar o estado global, como o status de login do usuário atual ou seu tema preferido.
Compreendendo a API React Context
Antes de mergulhar no código, é importante entenda o que é API React Context e qual problema ele aborda.
Props fornecem um método eficaz para compartilhar dados entre componentes. Eles permitem que você passe dados de um componente pai para seus componentes filhos.
Essa abordagem é útil porque mostra claramente quais componentes usam determinados dados e como esses dados fluem pela árvore de componentes.
No entanto, surgem problemas quando você tem componentes profundamente aninhados que precisam consumir os mesmos adereços. Essa situação pode introduzir complexidades e potencialmente resultar em código complicado e mais difícil de manter. Estas questões, entre outras, são as desvantagens da perfuração de hélice.
O React Context resolve esse desafio fornecendo um método centralizado para criar e usar dados que precisam ser acessíveis globalmente, entre componentes.
Ele configura um contexto para armazenar esses dados, permitindo que os componentes os acessem. Essa abordagem ajuda a estruturar sua base de código para garantir que esteja bem organizada.
Você pode encontrar o código deste projeto em seu GitHub repositório.
Primeiros passos com gerenciamento de estado em Next.js 13 usando React Context API
Os componentes do servidor Next.js permitem que você crie aplicativos que aproveitam o melhor dos dois mundos: a interatividade dos aplicativos do lado do cliente e os benefícios de desempenho da renderização do servidor.
Next.js 13 implementa componentes de servidor no aplicativo diretório - que agora é estável - por padrão. No entanto, como todos os componentes são renderizados pelo servidor, você pode ter problemas ao integrar bibliotecas ou APIs do lado do cliente, como React Context.
Para evitar isso, uma ótima solução alternativa é o usar cliente sinalizador que você pode definir em arquivos que executarão o código do lado do cliente.
Para começar, crie um projeto Next.js 13 localmente executando este comando em seu terminal:
npx create-next-app@latest next-context-api
Após criar o projeto, navegue até seu diretório:
cd next-context-api
Em seguida, inicie o servidor de desenvolvimento:
npm run dev
Depois de configurar um projeto Next.js básico, você pode construir um aplicativo de tarefas básico que utiliza a API React Context para gerenciamento de estado.
Crie o provedor de contexto
O arquivo do provedor de contexto serve como um hub central onde você define e gerencia o estado global que os componentes precisam acessar.
Crie um novo arquivo, src/context/Todo.context.jse preencha-o com o código a seguir.
"use client"
import React, { createContext, useReducer } from"react";
const initialState = {
todos: [],
};const reducer = (state, action) => {
switch (action.type) {
case"ADD_TODO":
return { ...state, todos: [...state.todos, action.payload] };case"DELETE_TODO":
return { ...state, todos: state.todos.filter((todo, index) =>
index !== action.payload) };case"EDIT_TODO":
const updatedTodos = state.todos.map((todo, index) =>
index action.payload.index? action.payload.newTodo: todo);
return { ...state, todos: updatedTodos };default:
return state;
}
};exportconst TodoContext = createContext({
state: initialState,
dispatch: () =>null,
});exportconst TodoContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
{children}
</TodoContext.Provider>
);
};
Esta configuração do React Context define um TodoContext que inicialmente mantém o estado de uma lista de tarefas vazia para o aplicativo.
Além de criar o estado inicial, esta configuração de contexto inclui um redutor função que define vários tipos de ação. Esses tipos de ação modificarão o estado do contexto dependendo das ações acionadas. Nesse caso, as ações incluem adicionar, excluir e editar tarefas.
O TodoContextProvider componente fornece o TodoContext para outros componentes do aplicativo. Este componente leva dois adereços: o valor prop, que é o estado inicial do contexto, e o redutor prop, que é a função redutora.
Quando um componente consome TodoContext, ele pode acessar o estado do contexto e despachar ações para atualizar o estado.
Adicione o provedor de contexto ao aplicativo Next.js
Agora, para garantir que o provedor de contexto seja renderizado na raiz do seu aplicativo Next.js e que todos os componentes do cliente possam acessá-lo, você precisa adicionar o contexto ao componente de layout raiz do aplicativo.
Para fazer isso, abra o src/app/layout.js arquivo e envolva o nó filho no modelo HTML com o provedor de contexto da seguinte maneira:
import'./globals.css';
import { TodoContextProvider } from"@/context/Todo.context";exportconst metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
exportdefaultfunctionRootLayout({
children
}) {
return (
"en">{children}</TodoContextProvider>
</body>
</html>
);
}
Crie um componente de tarefas pendentes
Crie um novo arquivo, src/componentes/Todo.jse adicione o seguinte código a ele.
Comece fazendo as seguintes importações. Certifique-se de incluir o usar cliente sinalizador para marcar este componente como um componente do lado do cliente.
"use client"
import { TodoContext } from"@/context/Todo.context";
import React, { useContext, useState } from"react";
A seguir, defina o componente funcional, incluindo os elementos JSX que serão renderizados no navegador.
exportdefaultfunctionTodo() {
return (marginBottom: "4rem", textAlign: "center" }}>Todos</h2>
type="text"
value={todoText}
onChange={(e) => setTodoText(e.target.value)}
style={{ marginBottom: 16}}
placeholder="Enter a todo"
/>
{state.todos.map((todo, index) => (
{index editingIndex? (
<>
type="text"
value={editedTodo}
onChange={(e) => setEditedTodo(e.target.value)}
/>style={{ marginRight: 16}}
onClick={() => handleEditTodo(index, editedTodo)}
>
Save
</button>
</>
): (
<>
{todo}
style={{ marginRight: 16}}
onClick={() => setEditingIndex(index)}
>Edit</button>
onClick={() => handleDeleteTodo(index)}
>Delete</button>
</>
)}
</li>
))}
</ul>
</div>
);
}
Este componente funcional inclui campos de entrada para adicionar, editar e excluir tarefas, juntamente com os botões correspondentes. Ele usa Renderização condicional do React para mostrar os botões de edição e exclusão com base no valor do índice de edição.
Por último, defina as variáveis de estado necessárias e as funções de manipulador necessárias para cada tipo de ação. Dentro do componente de função, adicione o código a seguir.
const { state, dispatch } = useContext(TodoContext);
const [todoText, setTodoText] = useState("");
const [editingIndex, setEditingIndex] = useState(-1);
const [editedTodo, setEditedTodo] = useState("");const handleAddTodo = () => {
if (todoText.trim() !== "") {
dispatch({ type: "ADD_TODO", payload: todoText });
setTodoText("");
}
};const handleDeleteTodo = (index) => {
dispatch({ type: "DELETE_TODO", payload: index });
};
const handleEditTodo = (index, newTodo) => {
dispatch({ type: "EDIT_TODO", payload: { index, newTodo } });
setEditingIndex(-1);
setEditedTodo("");
};
Essas funções manipuladoras são responsáveis por lidar com a adição, exclusão e edição das tarefas de um usuário dentro do estado do contexto.
Eles garantem que quando um usuário adiciona, exclui ou edita uma tarefa, as ações apropriadas são enviadas ao redutor do contexto para atualizar o estado adequadamente.
Renderizar o componente de tarefas pendentes
Por fim, importe o componente To-do para o componente page.
Para fazer isso, abra o arquivo page.js no diretório src/app, exclua o código Next.js padrão e adicione o código abaixo:
import styles from'./page.module.css'
import Todo from'../components/Todo'
exportdefaultfunctionHome() {
return (
</main>
)
}
Ótimo! Neste ponto, você deve ser capaz de gerenciar o estado no aplicativo To-do Next.js usando React Context.
Usando a API React Context com outras tecnologias de gerenciamento de estado
A API React Context é uma ótima solução para gerenciamento de estado. No entanto, é possível usá-lo junto com outras bibliotecas de gerenciamento de estado, como Redux. Essa abordagem híbrida garante que você use a melhor ferramenta para diferentes partes do seu aplicativo que desempenham funções importantes.
Ao fazer isso, você pode aproveitar os benefícios de diferentes soluções de gerenciamento de estado para criar aplicativos eficientes e de fácil manutenção.