Como usar o React Context para gerenciamento de estado no Next.js 13
O Next.js oferece várias abordagens para o gerenciamento de estado. Enquanto alguns desses métodos requerem a instalação de novas bibliotecas, a API Context do React é integrada, então é uma ótima maneira de reduzir dependências externas.
O React Context permite a transmissão sem esforço de informações através de uma hierarquia de componentes, evitando a necessidade de perfuração intrusiva de prop. Isso se mostra particularmente vantajoso na manutenção de dados relevantes globalmente, como o status de login do usuário autenticado no momento e seu tema preferido.
Entendendo a API de contexto do React
Para se aprofundar efetivamente na implementação do código, é crucial ter um entendimento abrangente da API de contexto do React e sua finalidade de lidar com desafios específicos.
A utilização de adereços permite uma transmissão perfeita de informações entre elementos interligados, facilitando a transferência de dados de um componente superior para os seus homólogos subordinados através de uma estrutura hierárquica.
Este método revela-se vantajoso, uma vez que demonstra inequivocamente os componentes específicos que dependem de determinada informação, juntamente com a progressão subsequente desses dados ao longo da estrutura hierárquica dos componentes.
No entanto, podem surgir dificuldades quando os componentes com um aninhamento complexo exigem a partilha de adereços idênticos. Tais circunstâncias podem dar origem a complicações e, eventualmente, culminar num código complicado que é mais difícil de manter. Entre estas preocupações, bem como outras, contam-se as desvantagens associadas à perfuração de adereços.
O React Context aborda a questão do acesso a dados globais, oferecendo uma abordagem unificada para a criação e utilização de informações que devem estar disponíveis em vários componentes de uma aplicação.
A utilização de um contentor de dados estruturados facilita a recuperação e a manipulação de informações por vários componentes do sistema. A eficiência organizacional é assim melhorada, garantindo uma funcionalidade óptima numa rede complexa.
O código fonte deste projeto está alojado no nosso repositório GitHub, que pode ser acedido pelas partes interessadas.
Introdução ao gerenciamento de estados no Next.js 13 Usando a API de contexto do React
Os componentes de servidor do Next.js permitem que os desenvolvedores criem aplicativos que integram perfeitamente a capacidade de resposta das plataformas do lado do cliente com os ganhos de eficiência associados ao conteúdo renderizado no servidor, oferecendo assim uma experiência de usuário superior e otimizando o desempenho.
A versão 13 do Next.js incorporou componentes do servidor no diretório do aplicativo por padrão, o que agora é considerado estável. No entanto, deve-se observar que, como todos os componentes são renderizados no lado do servidor, podem surgir problemas ao tentar integrar bibliotecas ou APIs do lado do cliente, como o React Context.
Uma solução eficaz para evitar esse problema envolve a utilização do sinalizador “client”, que pode ser aplicado a arquivos JavaScript para execução de código do lado do cliente.
Para iniciar o processo, você pode estabelecer um ambiente de desenvolvimento Next.js 13 em seu computador local usando as seguintes etapas no terminal:
npx create-next-app@latest next-context-api
Para acessar o diretório de um projeto recém-criado de maneira sofisticada, siga estas etapas:1. Depois de estabelecer o projeto usando uma metodologia apropriada, localize sua localização física no sistema de arquivos navegando pela estrutura hierárquica de diretórios e arquivos até chegar à pasta designada que contém todos os componentes relacionados ao projeto. Este processo pode envolver a utilização de interfaces de linha de comandos ou de interfaces gráficas de utilizador, dependendo do seu sistema operativo e das suas preferências.
cd next-context-api
Em seguida, inicie o servidor de desenvolvimento:
npm run dev
Após estabelecer uma estrutura de projeto Next.js fundamental, é possível construir um aplicativo gerenciador de tarefas rudimentar aproveitando a API React Context como seu principal meio de governança de estado.
Criar o provedor de contexto
A função de provedor de contexto atua como uma fonte primária da qual vários componentes derivam as informações globais necessárias, permitindo que eles interajam com seu ambiente de forma eficaz.
Crie um novo arquivo chamado src/context/Todo.context.js
no diretório do seu projeto e cole o seguinte código nele:javascriptimport { defineContext } from ‘vuex’;export default defineContext({id: ’todo’,state: () => ({todos: [],selectedTodo: null,isAllChecked: false,showForm: false,}),mutations: {setTodos(state, value) {state.todos = value;},addTodo(state, todo) {if (!state.todos.length) {return;}const updatedTodos = […state.todos
"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;
}
};
export const TodoContext = createContext({
state: initialState,
dispatch: () => null,
});
export const TodoContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<TodoContext.Provider value={{ state, dispatch }}>
{children}
</TodoContext.Provider>
);
};
A presente configuração estabelece uma estrutura contextual para o React, referida como “TodoContext”, que começa com uma lista de tarefas vazia como o estado inicial da aplicação.
Para além de estabelecer o estado inicial, esta configuração de contexto incorpora uma função redutora que define vários tipos de ação. A implementação destes tipos de ação provocará alterações no estado do contexto com base nas operações executadas.Por exemplo, estas acções podem envolver a inserção, remoção ou modificação de itens de tarefas dentro do contexto.
o valor
prop, que representa o estado inicial do contexto, e o redutor
prop, que designa a função da operação de redução.
Após a ingestão do TodoContext por um determinado elemento, o estado atual do referido contexto é recuperável, juntamente com a capacidade de propagar sinais para alterar a sua disposição.
Adicionar o provedor de contexto ao aplicativo Next.js
Para que o provedor de contexto seja renderizado no nível superior do aplicativo Next.js, garantindo que todos os componentes do lado do cliente tenham acesso a ele, é necessário incluir o contexto no componente de layout raiz do aplicativo.
Para realizar esta tarefa, aceda ao ficheiro “src/app/layout.js” e inclua os nós filhos num modelo HTML utilizando um fornecedor de contexto, conforme demonstrado abaixo:
import './globals.css';
import { TodoContextProvider } from "@/context/Todo.context";
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children
}) {
return (
<html lang="en">
<body>
<TodoContextProvider>{children}</TodoContextProvider>
</body>
</html>
);
}
Criar um componente To-Do
Para criar um novo ficheiro na estrutura de directórios especificada, siga estes passos:1. abra o seu editor de texto preferido ou o ambiente de desenvolvimento integrado (IDE).2. navegue até à pasta “src” do seu projeto.3.Dentro da pasta “src”, localize e seleccione a subpasta “components”.4. Clique no botão “New File” no seu editor de texto ou IDE para gerar um novo documento em branco.5. Guarde o ficheiro recém-criado com o nome “Todo.js”. Isto deve ser feito tanto na subpasta “components” como na pasta geral “src”.6. Assim que o ficheiro tiver sido guardado, pode então copiar e colar o fragmento de código fornecido no novo ficheiro “Todo.js”. Certifique-se de que a indentação
Incorpore as instruções de importação necessárias, incluindo o sinalizador use client
, e designe esse componente como um componente do lado do cliente, utilizando os sinalizadores apropriados no trecho de código abaixo:javascriptimport { use client } from ’next/client’;const MyComponent = () => {const [data, setData] = useState([]);// Use o sinalizador do cliente aqui…return ( {/* O JSX do seu componente vai aqui */} );};export default MyComponent;
"use client"
import { TodoContext } from "@/context/Todo.context";
import React, { useContext, useState } from "react";
Em seguida, vamos delinear o aspeto funcional da nossa aplicação, especificando os componentes HTML a serem renderizados no navegador da Web utilizando a JavaScript Extensible Markup Language (JSX).
export default function Todo() {
return (
<div style={{ marginBottom: "4rem", textAlign: "center" }}>
<h2>Todos</h2>
<input
type="text"
value={todoText}
onChange={(e) => setTodoText(e.target.value)}
style={{ marginBottom: 16}}
placeholder="Enter a todo"
/>
<button onClick={handleAddTodo}>Add Todo</button>
<ul>
{state.todos.map((todo, index) => (
<li key={index}>
{index === editingIndex ? (
<>
<input
type="text"
value={editedTodo}
onChange={(e) => setEditedTodo(e.target.value)}
/>
<button
style={{ marginRight: 16}}
onClick={() => handleEditTodo(index, editedTodo)}
>
Save
</button>
</>
) : (
<>
{todo}
<button
style={{ marginRight: 16}}
onClick={() => setEditingIndex(index)}
>Edit</button>
<button
onClick={() => handleDeleteTodo(index)}
>Delete</button>
</>
)}
</li>
))}
</ul>
</div>
);
}
Este componente funcional inclui elementos interactivos para adicionar, modificar e apagar tarefas numa lista.Esses componentes são construídos usando os recursos de renderização condicional do React, que exibem os botões de edição e remoção de acordo com o valor atual da variável de indexação.
Por fim, é necessário especificar as variáveis de estado necessárias e implementar funções de tratamento apropriadas para cada tipo de ação no corpo do componente funcional. Para isso, incorporar as seguintes linhas de código.
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("");
};
As responsabilidades funcionais acima mencionadas abrangem a gestão das tarefas de um utilizador no estado do contexto, incluindo a adição, remoção e modificação do mesmo.
O middleware é responsável por garantir que quaisquer alterações feitas por um utilizador às suas tarefas, tais como a adição, eliminação ou edição das mesmas, resultam no envio das actualizações correctas para o redutor do armazenamento, de modo a que este possa gerir e manter uma representação exacta do estado da aplicação.
Renderizar o componente To-Do
Incorporar o componente To-do no contexto do componente de página, importando-o.
Para executar a tarefa pretendida, aceda ao ficheiro “page.js” localizado na pasta “src/app” do seu projeto. Depois de aceder a este ficheiro, remova qualquer código pré-existente desnecessário associado ao Next.js e insira o fragmento de código fornecido.
import styles from './page.module.css'
import Todo from '../components/Todo'
export default function Home() {
return (
<main className={styles.main}>
<Todo />
</main>
)
}
De facto, com a implementação do React Context na aplicação To-do Next.js, é possível tratar e manipular eficazmente o processo de gestão do estado de uma forma mais eficiente.
Usando a API React Context com outras tecnologias de gerenciamento de estado
A integração da API React Context com soluções adicionais de gerenciamento de estado, como o Redux, oferece uma oportunidade de aproveitar os benefícios de ambos os sistemas em conjunto. Ao empregar esta estratégia híbrida, os programadores podem capitalizar os pontos fortes de cada tecnologia respectiva e otimizar o desempenho da sua aplicação utilizando as ferramentas mais adequadas para componentes críticos específicos dentro da arquitetura do software.
Através desta abordagem, é possível aproveitar as vantagens oferecidas por vários métodos de gestão de estados para desenvolver sistemas de software eficazes e bem organizados.