Como integrar ReactJS com programa Solana - Parte 2

Web3 e Blockchain

Como integrar ReactJS com programa Solana - Parte 2

Luiz Duarte
Escrito por Luiz Duarte em 23/07/2026
Junte-se a mais de 34 mil devs

Entre para minha lista e receba conteúdos exclusivos e com prioridade

Na primeira parte deste tutorial, que saiu recentemente aqui no site, a gente fez o setup inicial da aplicação e a primeira funcionalidade que era de inicialização do programa Solana na blockchain. Nesta segunda etapa, eu vou implementar o CRUD de livros através do frontend, conforme combinado.

Vamos lá!

#1 – Cadastrando um Livro

Para conseguir cadastrar um livro nós temos alguns desafios antes. Um deles nós solucionamos na primeira etapa, onde tínhamos de descobrir o PDA da library, lembra? O segundo é descobrir qual o ID do próximo livro a ser cadastrado. Isso porque os PDAs de livros usam do seu id como seed do endereço.

O próximo ID é uma característica gerenciada pela account de library, então vamos no Web3Service.ts criar uma função que traz essa informação pra gente.

Na getNextBookId nós pegamos o PDA da library, depois retornamos a account diretamente da blockchain, disparando um erro caso ela não exista. Só que essa account vem codificada em binário, um formato não muito útil para o frontend, certo? Neste caso precisamos de uma função de decodificação, que criaremos como abaixo.

Essa função usa o objeto accountsCoder para decodificar os bytes seguindo a lógica que a struct se chama Library e que dentro dela tem next_id e authority.

O próximo desafio para criação de um novo livro, considerando que cada um deles é salvo em seu próprio PDA Account, é derivar seu endereço usando as seeds. Coisa que a função getBookPda vai fazer pra gente.

Atenção especial aqui à passagem do bookId, que é um BN (bignumber) mas que deve ser passado como array de bytes little endian (le). Como nossos bookIds são u32, ou seja usigned integers de 32-bit, o toArray deve usar 4 no parâmetro length pois são 4 bytes por ID.

Agora sim podemos criar a função addBook no Web3Service.ts pois resolvemos todas as dependências de outras funções.

A função addBook espera o livro a ser cadastrado, a carteira do usuário (previamente conectada) e a conexão.

Ela começa pegando o PDA da library e com ele o próximo ID do livro a ser cadastrado. Com essas informações é possível derivar o endereço da PDA Account de livro e com isso enviar a transação de criação do mesmo.

A transação de criação de livro é uma chamada à função “add_book” contendo um book no objeto de instruções. Depois passa-se a wallet, a connection e o array de accounts a serem usadas no contexto da transação, conform exigido pelo programa.

Com a função pronta no Web3Service.ts, podemos partir para a criação de um componente BookForm.tsx para o form de cadastro/edição, a começar pelos imports.

E depois os states e uso de hooks.

O formulário em si é bem simples e não tem nada demais. Apenas vai pegando os valores dos inputs e jogando no state de book.

Quando o botão é clicado, dispara uma função onSaveClick como abaixo.

Essa função se encarrega de algumas validações em caso de cadastro de novo livro e de carteira já conectada. Tudo estando certo, ela verifica se é um novo cadastro e chama a função correspondente. A aparência do form pode ser vista abaixo e ele já deve estar funcional para ser usado.

#2 – Pesquisa e Edição de Livro

Antes de fazer a implementação para edição acho importante implementarmos a pesquisa primeiro, já que sem ela não temos como saber se de fato o cadastro e, mais tarde, a edição, estão funcionando.

Para a pesquisa, vamos voltar no Web3Service.ts para criar uma função que decodifica os bytes de um livro para um objeto legível.

Já fizemos isso antes, mas para library, lembra? A lógica aqui é a mesma mas ajustando à realidade da struct de livro.

Na sequência, vamos criar a função getBookData, que servirá como função de pesquisa, pois recebe um ID de livro e procura a account dele na blockchain, decodificando os bytes encontrados ou um erro caso não encontre.

Agora para a UI, crie um componente BookSearch.tsx com os seguintes imports:

E os seguintes states e uso de hooks.

Com isso tudo preparado, criar o form de pesquisa é bem simples, como abaixo.

E a função que o botão de pesquisar chama, pode ser vista a seguir.

Isso te dará uma aparência como abaixo, bem como a funcionalidade de informar um ID de livro e ver se ele existe ou não, o que você deve testar antes de prosseguir.

Terminada a funcionalidade de pesquisar, agora podemos ver se os livros estão sendo cadastrados corretamente. Eles estando, é hora de fazermos a edição, primeiramente adicionando uma nova função no Web3Service.ts para esta finalidade, que usa diversas outras funções que já criamos anteriormente.

Com a função pronta, basta alguns ajustes no componente BookForm.tsx para que ele funcione para edições também. A primeira é importar a função editBook do Web3Service.ts no topo do componente e a outra é ajustar a função de click do botão para, em caso do id ser preenchido, chamar a edição ao invés de criação, como abaixo.

Com isso, matamos agora mais duas funcionalidades do CRUD, faltando apenas a última, de exclusão.

#3 – Exclusão de Livro

A última funcionalidade que vamos adicionar no nosso dapp é de excluir livros previamente cadastrados. Para isso vamos criar uma nova função no Web3Service.ts chamada deleteBook, como abaixo.

Esta função não tem absolutamente nenhuma novidade frente à anteriores, então vamos para a criação do componente BookDelete.tsx, a começar pelos seus imports.

Depois os seus states e uso de hooks.

Na sequência sua UI (que é quase idêntica à de pesquisa):

E por último a função de click do botão de exclusão.

Nenhuma novidade nestas etapas. Importe este componente no App.tsx, posicione-o e terá algo como abaixo.

Agora você pode testar todas as operações básicas do CRUD com perfeição, finalizando a nossa implementação de um primeiro dapp web3 React + Solana.

Um abraço e até a próxima!

TAGS:

Olá, tudo bem?

O que você achou deste conteúdo? Conte nos comentários.

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *