{"id":2025,"date":"2026-06-22T12:12:24","date_gmt":"2026-06-22T15:12:24","guid":{"rendered":"https:\/\/desvendandoocodigo.com.br\/?p=2025"},"modified":"2026-06-22T12:27:53","modified_gmt":"2026-06-22T15:27:53","slug":"como-criar-um-sistema-completo-com-react-node-js-e-mysql-projeto-full-stack","status":"publish","type":"post","link":"https:\/\/desvendandoocodigo.com.br\/?p=2025","title":{"rendered":"Como Criar um Sistema Completo com React, Node.js e MySQL | Projeto Full Stack"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\"><\/h1>\n\n\n\n<p><strong>Se voc\u00ea est\u00e1 aprendendo React e Node.js, uma das maiores d\u00favidas \u00e9:<\/strong><\/p>\n\n\n\n<p>Como os dados saem do formul\u00e1rio, passam pela API e s\u00e3o salvos no banco de dados?<\/p>\n\n\n\n<p>Neste projeto Full Stack vamos construir uma aplica\u00e7\u00e3o completa de agendamento, utilizando React no Front-end, Node.js e Express no Back-end e MySQL como banco de dados.<\/p>\n\n\n\n<p>Mais importante do que decorar c\u00f3digo, \u00e9 entender como as tecnologias trabalham juntas.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Projeto funcionando<\/h2>\n\n\n\n<p>Antes de come\u00e7ar a codificar, \u00e9 importante visualizar o resultado final.<\/p>\n\n\n\n<p>O sistema permite:<\/p>\n\n\n\n<ul>\n<li>Informar o nome do cliente.<\/li>\n\n\n\n<li>Escolher o procedimento.<\/li>\n\n\n\n<li>Definir data e hor\u00e1rio.<\/li>\n\n\n\n<li>Enviar os dados para uma API.<\/li>\n\n\n\n<li>Salvar as informa\u00e7\u00f5es no banco de dados MySQL.<\/li>\n\n\n\n<li>Retornar uma mensagem de confirma\u00e7\u00e3o para o usu\u00e1rio.<\/li>\n<\/ul>\n\n\n\n<p>Esse \u00e9 um excelente projeto para quem quer entender como funciona uma aplica\u00e7\u00e3o Full Stack na pr\u00e1tica.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Tecnologias utilizadas<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">React<\/h2>\n\n\n\n<p>No Front-end utilizamos:<\/p>\n\n\n\n<ul>\n<li>JSX<\/li>\n\n\n\n<li>Componentes<\/li>\n\n\n\n<li>useState<\/li>\n\n\n\n<li>Inputs controlados<\/li>\n\n\n\n<li>Eventos<\/li>\n\n\n\n<li>Fetch API<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Node.js + Express<\/h2>\n\n\n\n<p>No Back-end utilizamos:<\/p>\n\n\n\n<ul>\n<li>Express<\/li>\n\n\n\n<li>Rotas POST<\/li>\n\n\n\n<li>Fun\u00e7\u00f5es ass\u00edncronas<\/li>\n\n\n\n<li>JSON<\/li>\n\n\n\n<li>Tratamento de erros<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Banco de dados MySQL<\/h2>\n\n\n\n<p>No banco de dados utilizamos:<\/p>\n\n\n\n<ul>\n<li>Tabela de agendamentos<\/li>\n\n\n\n<li>INSERT<\/li>\n\n\n\n<li>MySQL2<\/li>\n\n\n\n<li>Create Connection<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Estrutura do projeto<\/h1>\n\n\n\n<p>O projeto \u00e9 dividido em duas partes:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Front-end<\/h2>\n\n\n\n<p>React respons\u00e1vel por:<\/p>\n\n\n\n<ul>\n<li>Formul\u00e1rio<\/li>\n\n\n\n<li>Captura dos dados<\/li>\n\n\n\n<li>Comunica\u00e7\u00e3o com a API<\/li>\n\n\n\n<li>Exibi\u00e7\u00e3o das respostas<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Back-end<\/h2>\n\n\n\n<p>Node.js respons\u00e1vel por:<\/p>\n\n\n\n<ul>\n<li>Receber as informa\u00e7\u00f5es<\/li>\n\n\n\n<li>Processar os dados<\/li>\n\n\n\n<li>Salvar no MySQL<\/li>\n\n\n\n<li>Retornar uma resposta para o React<\/li>\n<\/ul>\n\n\n\n<p>S\u00e3o dois servidores diferentes se comunicando entre si.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Instalando os pacotes<\/h1>\n\n\n\n<p>No Back-end utilizamos:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Express<\/h3>\n\n\n\n<p>Respons\u00e1vel pela constru\u00e7\u00e3o da API.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">MySQL2<\/h3>\n\n\n\n<p>Respons\u00e1vel pela comunica\u00e7\u00e3o com o banco de dados.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Cors<\/h3>\n\n\n\n<p>Permite que o Front-end consiga acessar o servidor Node.js.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Nodemon<\/h3>\n\n\n\n<p>Facilita o desenvolvimento reiniciando automaticamente o servidor.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Criando a API com Express<\/h1>\n\n\n\n<p>Criamos uma rota POST respons\u00e1vel por receber os dados do formul\u00e1rio:<\/p>\n\n\n\n<ul>\n<li>Nome<\/li>\n\n\n\n<li>Procedimento<\/li>\n\n\n\n<li>Dia<\/li>\n\n\n\n<li>Hora<\/li>\n<\/ul>\n\n\n\n<p>Esses dados chegam atrav\u00e9s do JSON enviado pelo React.<\/p>\n\n\n\n<p>Depois fazemos a desestrutura\u00e7\u00e3o das informa\u00e7\u00f5es para trabalhar com elas no servidor.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Conectando ao banco MySQL<\/h1>\n\n\n\n<p>Utilizamos o pacote mysql2 e criamos uma conex\u00e3o com:<\/p>\n\n\n\n<ul>\n<li>Usu\u00e1rio<\/li>\n\n\n\n<li>Senha<\/li>\n\n\n\n<li>Database<\/li>\n<\/ul>\n\n\n\n<p>Depois disso, o Node.js passa a ter acesso ao banco de dados.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Inserindo os dados<\/h1>\n\n\n\n<p>Utilizamos um INSERT com par\u00e2metros:<\/p>\n\n\n\n<ul>\n<li>Nome<\/li>\n\n\n\n<li>Procedimento<\/li>\n\n\n\n<li>Dia<\/li>\n\n\n\n<li>Hora<\/li>\n<\/ul>\n\n\n\n<p>Essa abordagem evita SQL Injection e torna a aplica\u00e7\u00e3o mais segura.<\/p>\n\n\n\n<p>Ap\u00f3s salvar os dados, retornamos uma mensagem para o usu\u00e1rio.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Testando a API<\/h1>\n\n\n\n<p>Antes de conectar o React ao Back-end, utilizamos o Thunder Client.<\/p>\n\n\n\n<p>Isso permite validar:<\/p>\n\n\n\n<ul>\n<li>Se a rota est\u00e1 funcionando.<\/li>\n\n\n\n<li>Se o banco est\u00e1 recebendo os dados.<\/li>\n\n\n\n<li>Se a resposta est\u00e1 sendo retornada corretamente.<\/li>\n<\/ul>\n\n\n\n<p>Essa etapa \u00e9 muito importante para depurar aplica\u00e7\u00f5es.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Criando o formul\u00e1rio em React<\/h1>\n\n\n\n<p>No Front-end utilizamos useState para armazenar:<\/p>\n\n\n\n<ul>\n<li>nome<\/li>\n\n\n\n<li>procedimento<\/li>\n\n\n\n<li>dia<\/li>\n\n\n\n<li>hora<\/li>\n\n\n\n<li>mensagem<\/li>\n<\/ul>\n\n\n\n<p>Cada input \u00e9 controlado pelo React atrav\u00e9s do onChange.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">HandleSubmit e preventDefault<\/h1>\n\n\n\n<p>Criamos uma fun\u00e7\u00e3o handleSubmit para:<\/p>\n\n\n\n<ul>\n<li>Impedir o comportamento padr\u00e3o do formul\u00e1rio.<\/li>\n\n\n\n<li>Capturar os dados.<\/li>\n\n\n\n<li>Fazer a chamada da API.<\/li>\n<\/ul>\n\n\n\n<p>Essa fun\u00e7\u00e3o \u00e9 respons\u00e1vel por iniciar todo o fluxo do sistema.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Enviando os dados com Fetch API<\/h1>\n\n\n\n<p>Utilizamos:<\/p>\n\n\n\n<ul>\n<li>m\u00e9todo POST<\/li>\n\n\n\n<li>headers<\/li>\n\n\n\n<li>Content-Type application\/json<\/li>\n\n\n\n<li>JSON.stringify()<\/li>\n<\/ul>\n\n\n\n<p>Os dados s\u00e3o enviados para o servidor Node.js.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Tratando a resposta da API<\/h1>\n\n\n\n<p>Ap\u00f3s receber a resposta do servidor:<\/p>\n\n\n\n<ul>\n<li>Se tudo estiver correto, mostramos a mensagem de sucesso.<\/li>\n\n\n\n<li>Se ocorrer algum problema, exibimos uma mensagem de erro.<\/li>\n<\/ul>\n\n\n\n<p>Isso melhora a experi\u00eancia do usu\u00e1rio.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Criando os componentes<\/h1>\n\n\n\n<p>O projeto foi separado em componentes:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">AgendamentoForm<\/h3>\n\n\n\n<p>Respons\u00e1vel pelo formul\u00e1rio.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Resposta<\/h3>\n\n\n\n<p>Respons\u00e1vel por exibir a mensagem retornada pela API.<\/p>\n\n\n\n<p>Essa separa\u00e7\u00e3o deixa o c\u00f3digo mais organizado e facilita a manuten\u00e7\u00e3o.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Teste final<\/h1>\n\n\n\n<p>No final do projeto realizamos:<\/p>\n\n\n\n<p>\u2705 Teste do formul\u00e1rio.<\/p>\n\n\n\n<p>\u2705 Comunica\u00e7\u00e3o Front-end e Back-end.<\/p>\n\n\n\n<p>\u2705 Inser\u00e7\u00e3o no banco MySQL.<\/p>\n\n\n\n<p>\u2705 Valida\u00e7\u00e3o dos dados.<\/p>\n\n\n\n<p>\u2705 Confirma\u00e7\u00e3o do registro salvo.<\/p>\n\n\n\n<p>Tudo funcionando em uma aplica\u00e7\u00e3o Full Stack completa.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">O que voc\u00ea aprendeu<\/h1>\n\n\n\n<ul>\n<li>React<\/li>\n\n\n\n<li>JSX<\/li>\n\n\n\n<li>useState<\/li>\n\n\n\n<li>Inputs controlados<\/li>\n\n\n\n<li>Eventos<\/li>\n\n\n\n<li>Fetch API<\/li>\n\n\n\n<li>Node.js<\/li>\n\n\n\n<li>Express<\/li>\n\n\n\n<li>API REST<\/li>\n\n\n\n<li>CORS<\/li>\n\n\n\n<li>MySQL<\/li>\n\n\n\n<li>Thunder Client<\/li>\n\n\n\n<li>Comunica\u00e7\u00e3o Front-end + Back-end<\/li>\n\n\n\n<li>INSERT no banco de dados<\/li>\n\n\n\n<li>Componentiza\u00e7\u00e3o<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">V\u00eddeo deste projeto<\/h1>\n\n\n\n<p>\ud83c\udfa5 Assista ao v\u00eddeo:<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Como Criar um Sistema Completo com React, Node.js e MySQL | Projeto Full Stack\" width=\"960\" height=\"540\" src=\"https:\/\/www.youtube.com\/embed\/83WgFxy4BOE?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Live completa (1h30)<\/h1>\n\n\n\n<p>\ud83d\udcfa Live original:<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Mini Projeto React + Node.js (Agendamento de Barbearia) \u2014 Inser\u00e7\u00e3o e Consulta na Pr\u00e1tica\" width=\"960\" height=\"540\" src=\"https:\/\/www.youtube.com\/embed\/LG952qgN5Bo?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Conclus\u00e3o<\/h1>\n\n\n\n<p>Construir aplica\u00e7\u00f5es Full Stack n\u00e3o significa decorar centenas de comandos.<\/p>\n\n\n\n<p>Significa entender como as pe\u00e7as se conectam.<\/p>\n\n\n\n<p>React cuida da interface.<\/p>\n\n\n\n<p>Node.js recebe as informa\u00e7\u00f5es.<\/p>\n\n\n\n<p>MySQL armazena os dados.<\/p>\n\n\n\n<p>E juntos eles permitem criar sistemas reais.<\/p>\n\n\n\n<p>Aqui no Desvendando o C\u00f3digo, a ideia n\u00e3o \u00e9 apenas ensinar programa\u00e7\u00e3o.<\/p>\n\n\n\n<p>\u00c9 ajudar voc\u00ea a entender como a tecnologia funciona.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Se voc\u00ea est\u00e1 aprendendo React e Node.js, uma das maiores d\u00favidas \u00e9: Como os dados saem do formul\u00e1rio, passam pela API e s\u00e3o salvos no banco de dados? Neste projeto Full Stack vamos construir uma aplica\u00e7\u00e3o completa de agendamento, utilizando React no Front-end, Node.js e Express no Back-end e MySQL como banco de dados. Mais importante do que decorar c\u00f3digo, \u00e9 entender como as tecnologias trabalham juntas. Projeto funcionando Antes de come\u00e7ar a codificar, \u00e9 importante visualizar o resultado final. O sistema permite: Esse \u00e9 um excelente projeto para quem quer entender como funciona uma aplica\u00e7\u00e3o Full Stack na pr\u00e1tica. Tecnologias utilizadas React No Front-end utilizamos: Node.js + Express No Back-end utilizamos: Banco de dados MySQL No banco de dados utilizamos: Estrutura do projeto O projeto \u00e9 dividido em duas partes: Front-end React respons\u00e1vel por: Back-end Node.js respons\u00e1vel por: S\u00e3o dois servidores diferentes se comunicando entre si. Instalando os pacotes No Back-end utilizamos: Express Respons\u00e1vel pela constru\u00e7\u00e3o da API. MySQL2 Respons\u00e1vel pela comunica\u00e7\u00e3o com o banco de dados. Cors Permite que o Front-end consiga acessar o servidor Node.js. Nodemon Facilita o desenvolvimento reiniciando automaticamente o servidor. Criando a API com Express Criamos uma rota POST respons\u00e1vel por receber os dados do formul\u00e1rio: Esses dados chegam atrav\u00e9s do JSON enviado pelo React. Depois fazemos a desestrutura\u00e7\u00e3o das informa\u00e7\u00f5es para trabalhar com elas no servidor. Conectando ao banco MySQL Utilizamos o pacote mysql2 e criamos uma conex\u00e3o com: Depois disso, o Node.js passa a ter acesso ao banco de dados. Inserindo os dados Utilizamos um INSERT com par\u00e2metros: Essa abordagem evita SQL Injection e torna a aplica\u00e7\u00e3o mais segura. Ap\u00f3s salvar os dados, retornamos uma mensagem para o usu\u00e1rio. Testando a API Antes de conectar o React ao Back-end, utilizamos o Thunder Client. Isso permite validar: Essa etapa \u00e9 muito importante para depurar aplica\u00e7\u00f5es. Criando o formul\u00e1rio em React No Front-end utilizamos useState para armazenar: Cada input \u00e9 controlado pelo React atrav\u00e9s do onChange. HandleSubmit e preventDefault Criamos uma fun\u00e7\u00e3o handleSubmit para: Essa fun\u00e7\u00e3o \u00e9 respons\u00e1vel por iniciar todo o fluxo do sistema. Enviando os dados com Fetch API Utilizamos: Os dados s\u00e3o enviados para o servidor Node.js. Tratando a resposta da API Ap\u00f3s receber a resposta do servidor: Isso melhora a experi\u00eancia do usu\u00e1rio. Criando os componentes O projeto foi separado em componentes: AgendamentoForm Respons\u00e1vel pelo formul\u00e1rio. Resposta Respons\u00e1vel por exibir a mensagem retornada pela API. Essa separa\u00e7\u00e3o deixa o c\u00f3digo mais organizado e facilita a manuten\u00e7\u00e3o. Teste final No final do projeto realizamos: \u2705 Teste do formul\u00e1rio. \u2705 Comunica\u00e7\u00e3o Front-end e Back-end. \u2705 Inser\u00e7\u00e3o no banco MySQL. \u2705 Valida\u00e7\u00e3o dos dados. \u2705 Confirma\u00e7\u00e3o do registro salvo. Tudo funcionando em uma aplica\u00e7\u00e3o Full Stack completa. O que voc\u00ea aprendeu V\u00eddeo deste projeto \ud83c\udfa5 Assista ao v\u00eddeo: Live completa (1h30) \ud83d\udcfa Live original: Conclus\u00e3o Construir aplica\u00e7\u00f5es Full Stack n\u00e3o significa decorar centenas de comandos. Significa entender como as pe\u00e7as se conectam. React cuida da interface. Node.js recebe as informa\u00e7\u00f5es. MySQL armazena os dados. E juntos eles permitem criar sistemas reais. Aqui no Desvendando o C\u00f3digo, a ideia n\u00e3o \u00e9 apenas ensinar programa\u00e7\u00e3o. \u00c9 ajudar voc\u00ea a entender como a tecnologia funciona.<\/p>\n","protected":false},"author":1,"featured_media":2026,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=\/wp\/v2\/posts\/2025"}],"collection":[{"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2025"}],"version-history":[{"count":4,"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=\/wp\/v2\/posts\/2025\/revisions"}],"predecessor-version":[{"id":2037,"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=\/wp\/v2\/posts\/2025\/revisions\/2037"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=\/wp\/v2\/media\/2026"}],"wp:attachment":[{"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2025"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2025"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2025"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}