Building a React Data Grid CRUD Admin App 30 Minutes
Resumo; DR Se você já construiu um app CRUD de administrador antes, você conhece a rotina: uma grade quase certa, um formulário modal pela metade, um post-it "faremos edição de linha depois" e três semanas de tickets de "filtro não funciona em colunas de data". Reconstruí o console de administração clássico da Northwind em menos de 30 minutos — CRUD completo em todo o [...]
TL;DR
Se você já construiu um app CRUD de administrador antes, conhece a rotina: uma grade quase certa, um formulário modal pela metade, um post-it de "faremos edição de linha depois" e três semanas de tickets de "filtro não funciona em colunas de data".
Reconstruí o clássico console de administração da Northwind em menos de 30 minutos — CRUD completo entre pedidos, clientes, produtos, remetentes e vendedores — usando a Ignite UI React Data Grid para a interface e uma pequena API SQLite Core 10 + EF para o backend. Código total da interface: cerca de 1.500 linhas de TypeScript. Tempo total gasto lutando contra o grid: ~0 minutos.
Se você está avaliando um React Data Grid para um aplicativo de administração real, esse é o caso de uso que importa: edição inline, filtragem, dropdowns relacionais, validação, master-detail, resumos e temas que se mantêm juntos quando a página deixa de ser um brinquedo.
Repo: react-grids/react-data-grids-crud

Essa é a captura de tela que quero que você leve. Passe o mouse em qualquer linha → uma tira de ação desliza com Editar e Deletar. Clique em Editar → a linha se torna editável inline, aparecem chips de Salvar/Cancelar. Clique no menu suspenso → uma combinação de pesquisa enquanto digita com cabeçalhos agrupados. Selecione uma linha → um painel mestre-detalhe se abre abaixo dela com os dados combinados.
Isso não é uma construção personalizada. Isso é<IgrGrid rowEditable> um ponto positivo<IgrActionStrip><IgrGridEditingActions /></IgrActionStrip>. Vamos chegar ao código em um minuto.
Demonstrações CRUD são fáciles. Apps CRUD não são.
Aplicativos internos de administração estão por toda parte. Toda empresa tem isso. Eles nunca entram no demo reel. E ainda assim — linha por linha — eles são algumas das interfaces mais difíceis que você pode construir, porque os usuários realmente as usam todos os dias e percebem cada aresta bruta.
Uma página CRUD real precisa:
- Ordenação, filtragem, paginação (parece fácil — tente entre tipos de data e locais)
- Edição de linha inline com semântica adequada de salvar/cancelar e uma experiência de usuário otimista
- Uma forma de diálogo para criações com buscas relacionais ricas
- Validação que roda antes de você deixar o usuário salvar
- Detalhe mestre para que o usuário possa ver o contexto sem precisar clicar
- A delete confirmation that doesn’t feel hostile
- Carregamento, vazio ou estados de erro que comunicam claramente
- Acessibilidade do teclado, gerenciamento de foco, etiquetas de leitores de tela
A maioria das equipes envia 60% disso, declara vitória e entrega para os operadores com um encolher de ombros. Esse é o trabalho que a Ignite UI React Data Grid deveria desaparecer.
Configurando o backend CRUD com .NET Core, SQLite.
O back-end é puro padrão. Cinco entidades, um EF Core DbContext, cinco pequenos controladores CRUD, Swashbuckle para OpenAPI:
// server/Program.cs
builder.Services.AddDbContext<AppDbContext>(opts =>
opts.UseSqlite("Data Source=northwind.db"));
builder.Services.AddControllers();
builder.Services.AddSwaggerGen();
Os controles são exatamente o que você imagina:
// server/Controllers/ProductsController.cs
[ApiController, Route("api/[controller]")]
public class ProductsController(AppDbContext db) : ControllerBase
{
[HttpGet] public Task<List<Product>> GetAll() => db.Products.AsNoTracking().ToListAsync();
[HttpPost] public async Task<Product> Create(Product p) { db.Add(p); await db.SaveChangesAsync(); return p; }
[HttpPut("{id:int}")]public async Task Update(int id, Product p) { db.Update(p); await db.SaveChangesAsync(); }
[HttpDelete("{id:int}")] public async Task Delete(int id) { db.Remove(await db.Products.FindAsync(id)); await db.SaveChangesAsync(); }
}
dotnet rune você recebe uma interface Swagger em/swagger. Agora você pode ver — e chamar — todos os endpoints sem ainda escrever um frontend. Esse é o contrato que torna o lado React fácil: uma API REST tipada que a interface pode espelhar linha por linha.
A camada de serviço frontend espelha a API
// client/src/api/types.ts
export interface Product {
productID: number;
productName: string;
unitPrice: number;
stockLevel: number;
}
// client/src/api/services.ts
export const ProductsService = {
list: () => api.get<Product[]>('/api/Products'),
get: (id: number) => api.get<Product>(`/api/Products/${id}`),
create: (p: Omit<Product, 'productID'>) => api.post<Product>('/api/Products', p),
update: (p: Product) => api.put<void>(`/api/Products/${p.productID}`, p),
remove: (id: number) => api.del(`/api/Products/${id}`),
};
Os tipos TypeScript correspondem à forma JSON ASP.NET serializa por padrão, então não há camada de mapeamento para manter.
A parte sobre que todo este post é: a React Data Grid
Aqui está toda a fiação CRUD da página de Produtos.
import {
IgrGrid, IgrColumn, IgrPaginator,
IgrActionStrip, IgrGridEditingActions,
} from 'igniteui-react-grids';
<IgrGrid
data={filtered}
primaryKey="productID"
rowEditable={true}
allowFiltering={true}
filterMode="excelStyleFilter"
moving={true}
onRowEditDone={async (e: CustomEvent) => {
const row = (e.detail as { newValue?: Product })?.newValue;
if (!row) return;
try {
await ProductsService.update(row);
toast.success(`Product "${row.productName}" saved.`);
products.refetch();
} catch (err) {
toast.error(`Save failed: ${(err as Error).message}`);
}
}}
onRowDeleted={async (e: CustomEvent) => {
const row = (e.detail as { data?: Product })?.data;
if (!row) return;
try {
await ProductsService.remove(row.productID);
toast.success(`Deleted "${row.productName}".`);
products.refetch();
} catch (err) {
toast.error(`Delete failed: ${(err as Error).message}`);
}
}}
>
<IgrColumn field="productID" header="ID" editable={false} />
<IgrColumn field="productName" header="Product" editable={true} hasSummary />
<IgrColumn field="unitPrice" header="Price"
dataType="number" editable={true}
bodyTemplate={(c) => <span>{currency(c.cell.value)}</span>} />
<IgrColumn field="stockLevel" header="Stock"
dataType="number" editable={true} hasSummary />
<IgrPaginator perPage={10} />
<IgrActionStrip>
<IgrGridEditingActions addRow={false} />
</IgrActionStrip>
</IgrGrid>
Isso te dá um ponto:
- Sortable columns (click the header)
- Filtros de coluna no estilo Excel (o menu em cada cabeçalho)
- Paginação (15/30/45 por página) com paginador de rodapé
- Colunas de arrastar para reordenar
- Resumos numéricos e de sequência (média, soma, contagem) no rodapé
- Row paire → action strip com ícones de Editar/Excluir
- Clique em Editar → as células se tornam editáveis, chips de Salvar/Cancelar aparecem no final da fileira
onRowEditDonedispara com a nova linha → MESSA COLOCAR na APIonRowDeleteddispara quando o usuário confirma exclusão → DELETAÇÃO da API
A peça que quero destacar érowEditable={true} mais aIgrActionStrip + IgrGridEditingActions combinação. Você mesmo não acompanha o estado de edição e monitoramento. SemisEditing flag, sem mapa de "células sujas", sem o handler "o usuário apertou Escape". A React Data Grid gerencia isso; Você só escuta o commit e o envia para o seu serviço.
A outra parte é o render como quiser bodyTemplate. Estou formatandounitPrice como moeda no exemplo acima. O mesmo gancho permite renderizar pílulas de status, avatares, distintivos, níveis de ação codificados por cores — qualquer coisa que React possa renderizar — sem abrir mão de ordenar ou filtrar o valor subjacente.
Buscas relacionais pertencem a um Combo, não a uma entrada numérica
Edição inline é ótima para primitivos, mas se sua linha tem chaves estrangeiras (salesPersonID,productID,shipperID), você não quer que usuários digitem IDs. Você quer um menu suspenso pesquisável e agrupado.
Enter IgrCombo:
<IgrCombo
data={salespeople.map((s) => ({
id: s.salesPersonID,
name: fullName(s.salesPersonFirstName, s.salesPersonLastName),
subtitle: s.salesPersonTitle ?? '',
}))}
valueKey="id"
displayKey="name"
groupKey="subtitle" // ← grouped headers come for free
singleSelect
value={form.salesPersonID != null ? [form.salesPersonID] : []}
onChange={(e) => {
const arr = (e.detail as { newValue?: unknown[] }).newValue ?? [];
setForm((f) => ({ ...f, salesPersonID: (arr[0] as number) ?? null }));
}}
/>

Características empresariais em Ignite UI que seus usuários vão adorar – filtragem por digitação antecipada, seleção múltipla com renderização de chip, virtualização para milhares de itens e um slot para modelos personalizados de itens.
CombineIgrCombo comIgrDatePicker eIgrInput e você tem toda a história de "rico cria forma" sendo cuidada por Ignite UI React componentes.
Temática — uma importação, pronta
Quando comecei a construir esse app, eu tinha um único tema – o tema Material Light embutido, aplicado com uma importação CSS por arquivo:
// main.tsx import 'igniteui-webcomponents/themes/light/material.css'; import 'igniteui-react-grids/grids/themes/light/material.css';
Cada superfície Ignite UI— chevrons, a fita de ação, o lápis de edição, botões do paginador, cabeçalhos de diálogo — pega o tema automaticamente. À medida que o app evoluiu, adicionei um seletor para trocar temas baseados nos quatro sistemas de design já feitos (Material, Fluent, Indigo, Bootstrap) e variantes escuras para cada um. Troque uma importação CSS e o app inteiro muda os temas.
I also used the Ignite UI MCP servers
Construí isso usando os servidores Ignite UI MCP para componentes e tematização. Em vez de configurar cada página manualmente do zero, usei prompts para gerar e refinar a estrutura do app (front-end e back-end), uso de componentes e configuração visual em cerca de 20 minutos no total.
Se quiser ver exatamente como foi feito, o prompt está no repositório do GitHub aqui: docs/PROMPTS.md. A configuração MCP que usei é a Ignite UI CLI MCP mais o fluxo de trabalho MCP de tematizado.
O que eu não precisei construir
Para tornar a comparação concreta — aqui está o que eu não precisei escrever:
- Um renderizador de tabelas virtualizadas
- Gerenciamento de estado de edição de linhas
- Interface de filtro de colunas no estilo Excel
- Uma caixa de combinação agrupada com múltiplas seleções com digitação antecipada
- A date picker that renders a calendar
- Sincronização de rolagem entre navegadores
- Keyboard navigation across cells
- Gerenciamento de foco para o diálogo de edição
- Um renderizador de pílula de status com cores semânticas adequadas
- Toast / snackbar plumbing
- Estilo visual consistente em tudo isso acima
Esse é o valor que se destaca. A Ignite UI React Data Grid tem exatamente o formato do trabalho que você não quer fazer duas vezes.
Try it
A fonte completa está em github.com/react-grids/react-data-grids-crud. Clone, execute a API .NET, execute o servidor de desenvolvimento do Vite, e você terá um console CRUD funcionando em dois terminais.

Se quiser usar o React Data Grid no seu próprio app, comece pela página do Ignite UI React Data Grid e baixe um teste gratuito por lá.
Assista ao vídeo no YouTube:
A grade que usei aqui é o pacote comercialigniteui-react-grids. Também existe uma opção gratuitaIgrGridLite no MIT licenciadoigniteui-react/grid-lite se você não precisar de edição de linhas, master-detail ou a tira de ação.
Perguntas Freqüentes
Qual é a maneira mais rápida de construir um aplicativo de administrador CRUD em React?
O caminho mais rápido é começar com uma grade de dados React e formar componentes que já gerenciam as partes difíceis: edição, filtragem, paginação, buscas, validação e acessibilidade. Neste projeto, a Ignite UI React Data Grid mais uma pequena camada de serviço tipada removeu a maior parte da tubulação personalizada que normalmente retarda o trabalho com CRUD.
O que é uma React Data Grid e quando você precisa de uma?
Uma React Data Grid é um componente de tabela de alta função criado para telas interativas e com muitos dados. Você precisa de um quando seu app vai além das linhas somente leitura e começa a exigir edição inline, filtragem avançada, resumos, navegação por teclado, virtualização ou fluxos de trabalho de dados relacionais.
Dá para construir um app CRUD de verdade React com edição inline em minutos?
Sim, na verdade, você pode fazer isso em minutos. Esta demonstração inclui pedidos, clientes, produtos, remetentes e vendedores com edição de linha inline, criação de diálogos, confirmação de exclusão, detalhamento mestre e menu suspenso relacional em menos de 30 minutos usando a CLI Ignite UI e Claude Code ou GitHub Copilot.
Por que usar Ignite UI for React para aplicativos CRUD em vez de construir o comportamento da grade manualmente?
Porque a parte cara dos apps CRUD não é renderizar linhas. É o modelo de interação em torno dessas linhas: ciclo de vida de edição, filtragem de UX, comportamento do teclado, pesquisas agrupadas, resumos, tema e transições consistentes de estado. Ignite UI traz esses comportamentos como recursos do produto, então o código permanece focado em dados de negócios e chamadas de API.
Ignite UI for React funciona com um backend da API Web do .NET?
Sim. Neste exemplo, a interface se comunica com uma API SQLite do núcleo .NET 10 + EF sobre endpoints REST padrão. O código do cliente é simplesmente digitado TypeScript para funções/api/Products de serviço chamadas,/api/Orders e as outras rotas CRUD.
Você montou isso com os servidores Ignite UI MCP também?
Sim. O aplicativo usa Ignite UI componentes em tempo de execução, e o fluxo de trabalho de compilação também se beneficiou do Ignite UI CLI MCP e da configuração de MCP com temática. Essa combinação ajuda ferramentas de IA a estruturar páginas, responder perguntas sobre componentes e manter as decisões de tema alinhadas com Ignite UI padrões.
Is Ignite UI React Data Grid free?
O pacote completoigniteui-react-grids usado neste post é comercial. Se você só precisa de uma grade mais leve, Infragistics também oferece o gratuitoIgrGridLite no pacote licenciadoigniteui-react/grid-lite pelo MIT, embora recursos avançados de CRUD, como edição de linhas e tiras de ação, façam parte da oferta comercial.
Quais recursos são mais importantes em uma grade de dados CRUD de produção?
A base é ordenação, filtragem, paginação e edição. Na prática, as equipes também precisam de consultas relacionais, validação, confirmação de exclusão, acessibilidade do teclado, contexto mestre-detalhe, estados de carregamento e vazios, e uma tematização que não se desfaça quando você adiciona mais páginas. Essas são as características que tendem a decidir se uma ferramenta interna parece confiável ou frágil.
Tags: #react #react-data-grid #typescript #crud #datagrid #ignite-ui #dotnet #admin-ui #mcp