{"id":7242,"date":"2021-11-30T06:34:40","date_gmt":"2021-11-30T05:34:40","guid":{"rendered":"http:\/\/www.unimedia.tech.mialias.net\/build-a-simple-crud-app-using-react-and-node\/"},"modified":"2024-01-09T13:57:13","modified_gmt":"2024-01-09T12:57:13","slug":"build-a-simple-crud-app-using-react-and-node","status":"publish","type":"post","link":"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/","title":{"rendered":"Construir una simple aplicaci\u00f3n CRUD usando React y Node"},"content":{"rendered":"\n<p>En este art\u00edculo aprenderemos a crear una aplicaci\u00f3n CRUD sencilla con React.js, Node.js y TailwindCSS. <\/p>\n\n<h2 class=\"wp-block-heading\">\u00bfQu\u00e9 es una aplicaci\u00f3n CRUD?<\/h2>\n\n<p>Una aplicaci\u00f3n CRUD realiza cuatro operaciones b\u00e1sicas: <strong>crear<\/strong>, <strong>leer<\/strong>, <strong>actualizar<\/strong>y <strong>eliminar<\/strong>. Muchas aplicaciones con las que interact\u00faas a diario <a href=\"https:\/\/www.unimedia.tech\/software-development\/\">realizan <\/a>estas tareas b\u00e1sicas. Por ejemplo, Instagram. Puedes <strong>Crear <\/strong>perfiles y mensajes almacenados en la base de datos, <strong>Leer <\/strong>tus perfiles y mensajes y los de otros usuarios. Estos detalles se recuperan de los datos creados almacenados. Tambi\u00e9n puedes <strong>Actualizar y Eliminar<\/strong> tus publicaciones, fotos de perfil, etc. <\/p>\n\n<p>Tambi\u00e9n te puede interesar: <a href=\"https:\/\/www.unimedia.tech\/2021\/10\/09\/paypal-checkout-integration-with-react\/\">&#8220;Integraci\u00f3n de PayPal Checkout con React&#8221;<\/a><\/p>\n\n<p>Adem\u00e1s de requerir un Front-End y un servidor, estas funciones necesitan una base de datos como MongoDB para almacenar, recuperar, actualizar y eliminar los datos enviados por los usuarios. Como puedes imaginar, esto requiere un gran esfuerzo de configuraci\u00f3n, por lo que me alegr\u00e9 cuando descubr\u00ed una <a href=\"https:\/\/www.mecallapi.com\/#api\">sencilla API REST falsa <\/a>que podemos utilizar para realizar tareas CRUD b\u00e1sicas para nuestra aplicaci\u00f3n.<\/p>\n\n<h2 class=\"wp-block-heading\">Objetivo<\/h2>\n\n<p>Nuestro objetivo hoy es aprender las siguientes tareas:<\/p>\n\n<ul class=\"wp-block-list\"><li>Instalar paquetes b\u00e1sicos con Node.js<\/li><li>Crea una excelente interfaz de usuario usando React y Tailwind CSS<\/li><li>Realiza operaciones CRUD b\u00e1sicas con nuestra app.<\/li><\/ul>\n\n<h2 class=\"wp-block-heading\">Requisitos previos<\/h2>\n\n<ul class=\"wp-block-list\"><li>Conocimientos de React js y React Hooks.<\/li><li>React 16.8 o posterior<\/li><\/ul>\n\n<h2 class=\"wp-block-heading\">Crear una aplicaci\u00f3n React<\/h2>\n\n<p>Empecemos usando el boilerplate de React CRA para crear nuestra React App. Como vamos a utilizar Tailwind CSS, seguiremos los <a href=\"https:\/\/tailwindcss.com\/docs\/guides\/create-react-app\">pasos de la Documentaci\u00f3n Oficial<\/a> para que la instalaci\u00f3n sea fluida.<\/p>\n\n<p>Empieza con,<\/p>\n\n<pre class=\"wp-block-code\"><code>npx create-react-app my-react-crudapp\ncd my-react-crudapp\n<\/code><\/pre>\n\n<p>Abra la carpeta en su IDE favorito y complete el resto de los pasos. A continuaci\u00f3n, tenemos que instalar <a href=\"https:\/\/v5.reactrouter.com\/web\/guides\/quick-start\">React Router DOM<\/a> &#8211; una funcionalidad de enrutamiento que nos ayuda a navegar por nuestra aplicaci\u00f3n.<\/p>\n\n<pre class=\"wp-block-code\"><code>npm install react-router-dom<\/code><\/pre>\n\n<p>Ejecuta, <em>npm run start,<\/em> y deber\u00edas obtener la popular Welcome React Page como se muestra a continuaci\u00f3n. <\/p>\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2023\/12\/oqfRO0u2vQeEVdFhP7eLWJ1nD2ArUd1s9X9H6FRlzpxVBkrlZEEI4T_IkciUgMByjPSAAZiHJdZr-FpkYkDrBQW95dKs17iCR-9xtUvHkkEW9xt2hqUcou8Up3gUZU3_ANsIAifD.png\" alt=\"Aplicaci&#xF3;n React\"\/><\/figure>\n\n<p>En primer lugar, crearemos nuestro componente Navigation. Para ello, utilizaremos componentes de la p\u00e1gina de documentaci\u00f3n de Tailwind en la medida de lo posible.<br\/><br\/>Crea un componente <em>Naviagte.js <\/em>en tu <em>carpeta src.<\/em><\/p>\n\n<pre class=\"wp-block-code has-small-font-size\"><code>import React from \"react\";\nexport default function Navigate(){\n   return (\n       &lt;nav class=\"flex items-center justify-between flex-wrap bg-green-500 p-6\"&gt;\n           &lt;div class=\"flex items-center flex-shrink-0 text-white mr-6\"&gt;\n               &lt;span class=\"font-semibold text-xl tracking-tight\"&gt;REACT CRUD APP&lt;\/span&gt;\n           &lt;\/div&gt;          \n           &lt;div&gt;\n               &lt;button class=\"inline-block text-sm px-4 py-2 leading-none border rounded text-white border-white hover:border-transparent hover:text-green-500 hover:bg-white mt-4 lg:mt-0\"&gt;\n                   CREATE\n               &lt;\/button&gt;\n           &lt;\/div&gt;\n       &lt;\/nav&gt;\n   )\n}\n<\/code><\/pre>\n\n<p>A continuaci\u00f3n, llamaremos al <em>react-router-dom<\/em> y a nuestro <em>Navigate.js <\/em>en el Componente <em>principal App.js <\/em>. <\/p>\n\n<pre class=\"wp-block-code has-small-font-size\"><code>import { Link } from \"react-router-dom\";\nexport default function Navigate(){\n   return (\n       &lt;nav class=\"flex items-center justify-between flex-wrap bg-green-500 p-6\"&gt;\n       &lt;div class=\"flex items-center flex-shrink-0 text-white mr-6\"&gt;\n           &lt;span class=\"font-semibold text-xl tracking-tight\"&gt;REACT CRUD APP&lt;\/span&gt;\n       &lt;\/div&gt;\n       &lt;Link to=\"\/\"&gt;\n           &lt;button class=\"inline-block text-sm px-4 py-2 leading-none border rounded text-white border-white hover:border-transparent hover:text-green-500 hover:bg-white mt-4 lg:mt-0\"&gt;\n               HOME\n           &lt;\/button&gt;\n       &lt;\/Link&gt;\n       &lt;\/nav&gt;\n   )\n}\n<\/code><\/pre>\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2023\/12\/3A8UHiqnLUCfeaVbJdvuh705nZhMRTM65O6o6yPM2qk2uJK-5Dtor7CAi1qDyYCMBbk1Idohq7hsHzZc3nj-Bs_Aoo3fu2l0Vzx1HzavfCpyZkdWwdT3Ork4ZqcRLwpETKTa2fWi.png\" alt=\"Aplicaci&#xF3;n React CRUD\"\/><\/figure>\n\n<h2 class=\"wp-block-heading\">OPERACIONES DE CRUDO<\/h2>\n\n<p>Es hora de empezar a construir nuestras funcionalidades CRUD. Estas son las llamadas a la API que haremos para conseguirlo. <\/p>\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2023\/12\/iLjWBlGpe434PnimtEoPWTAwd7fAIYsahyjPFtZa_W_tEA7VxabKB4iRm5M0JRG7lxCXDXfT8SeZQ4q_f8yNzmXNrj1rHFrZzcx5Por7ONaX5c0xeXFnE-I7iDL_kvTepDh2DpFi.png\" alt=\"React CRUD App API\"\/><\/figure>\n\n<p>En primer lugar, vamos a crear un UsersList.js que nos ayudar\u00e1 a <strong>leer <\/strong>los usuarios existentes ya proporcionados por la API para las pruebas. Una vez m\u00e1s, vamos a ser <a href=\"https:\/\/tailwindui.com\/components\/application-ui\/lists\/tables\">un componente oficial de interfaz de usuario para construir esto<\/a>. <\/p>\n\n<h3 class=\"wp-block-heading\">UsersList.js<\/h3>\n\n<pre class=\"wp-block-code has-small-font-size\"><code>import React, { useEffect, useState } from \"react\";\nimport { Link } from \"react-router-dom\";\n \nfunction UsersList() {\n   const &#91;users, setUsers] = useState(&#91;]);\n   useEffect(() =&gt; {\n       ReadUsers()\n   }, &#91;])\n \n   const ReadUsers = () =&gt; {\n       fetch(\"https:\/\/www.mecallapi.com\/api\/users\")\n         .then(res =&gt; res.json())\n         .then(\n           (result) =&gt; {\n             setUsers(result)\n           }\n         )\n   }\n   return (\n       &lt;div class=\"flex flex-col\"&gt;\n           &lt;div class=\"-my-2 overflow-x-auto\"&gt;\n               &lt;div class=\"py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8\"&gt;\n                   &lt;div class=\"lg:flex lg:items-center lg:justify-between px-20 py-2\"&gt;\n                       &lt;div class=\"flex-1 min-w-0\"&gt;\n                           &lt;h2 class=\"text-2xl font-bold leading-7 text-gray-900 sm:text-3xl sm:truncate\"&gt;\n                           Users List\n                           &lt;\/h2&gt;\n                       &lt;\/div&gt;\n                       &lt;div class=\"mt-5 flex lg:mt-0 lg:ml-4\"&gt;\n                           &lt;span class=\"hidden sm:block\"&gt;\n                           &lt;Link to=\"\/create\"&gt;\n                               &lt;button type=\"button\" class=\"inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500\"&gt;\n                                   &lt;svg class=\"-ml-1 mr-2 h-5 w-5 text-gray-500\"  viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\"&gt;\n                                   &lt;path d=\"M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z\" \/&gt;\n                                   &lt;\/svg&gt;\n                                   CREATE\n                               &lt;\/button&gt;\n                           &lt;\/Link&gt;\n                           &lt;\/span&gt;\n                       &lt;\/div&gt;\n                   &lt;\/div&gt;\n               &lt;div class=\"shadow overflow-hidden border-b border-gray-200 sm:rounded-lg\"&gt;\n                   &lt;table class=\"min-w-full divide-y divide-gray-200\"&gt;\n                   &lt;thead class=\"bg-gray-50\"&gt;\n                       &lt;tr&gt;\n                       &lt;th scope=\"col\" class=\"px-10 py-1 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\"&gt;\n                           ID\n                       &lt;\/th&gt;\n                       &lt;th scope=\"col\" class=\"px-10 py-1 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\"&gt;\n                           Full Name\n                       &lt;\/th&gt;\n                       &lt;th scope=\"col\" class=\"px-6 py-1 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\"&gt;\n                           Email Address\n                       &lt;\/th&gt;\n                      \n                       &lt;th scope=\"col\" class=\"relative px-6 py-1\"&gt;\n                           &lt;span class=\"sr-only\"&gt;Edit&lt;\/span&gt;\n                       &lt;\/th&gt;\n                       &lt;\/tr&gt;\n                   &lt;\/thead&gt;\n                   &lt;tbody class=\"bg-white divide-y divide-gray-200\"&gt;\n                   {users.map((user) =&gt; (\n                       &lt;tr key={user.ID}&gt;\n                           &lt;td class=\"px-10 py-4 whitespace-nowrap\"&gt;\n                               &lt;div class=\"text-sm text-gray-500\"&gt;\n                                   {user.id}\n                               &lt;\/div&gt;\n                           &lt;\/td&gt;\n                           &lt;td class=\"px-6 py-4 whitespace-nowrap\"&gt;\n                               &lt;div class=\"flex items-center\"&gt;\n                               &lt;div class=\"flex-shrink-0 h-10 w-10\"&gt;\n                                   &lt;img class=\"h-10 w-10 rounded-full\" src={user.avatar} alt=\" \/&gt;\n                               &lt;\/div&gt;\n                               &lt;div class=\"ml-4\"&gt;\n                                   &lt;div class=\"text-sm font-medium text-gray-900\"&gt;\n                                  &lt;span&gt; {user.fname}&lt;\/span&gt; &lt;span&gt;{user.lname}&lt;\/span&gt;\n                                   &lt;\/div&gt;\n                               &lt;\/div&gt;\n                               &lt;\/div&gt;\n                           &lt;\/td&gt;\n                           &lt;td class=\"px-6 py-4 whitespace-nowrap\"&gt;\n                               &lt;div class=\"text-sm text-gray-500\"&gt;\n                                   {user.username}\n                               &lt;\/div&gt;\n                           &lt;\/td&gt;\n                           &lt;td class=\"px-6 py-4 space-x-2 whitespace-nowrap text-right text-sm font-medium\"&gt;\n                               &lt;button class=\"inline-block text-sm px-4 py-2 leading-none border rounded text-blue-800 border-blue-600 hover:bg-blue-300 hover:text-blue-500 mt-4 lg:mt-0\"&gt;EDIT&lt;\/button&gt;\n                               &lt;button class=\"inline-block text-sm px-4 py-2 leading-none border rounded text-red-800 border-red-600 hover:bg-red-300 hover:text-red-500 mt-4 lg:mt-0\"&gt;DELETE&lt;\/button&gt;\n                           &lt;\/td&gt;\n                       &lt;\/tr&gt;\n                       ))}\n                   &lt;\/tbody&gt;\n                   &lt;\/table&gt;\n               &lt;\/div&gt;\n               &lt;\/div&gt;\n           &lt;\/div&gt;\n       &lt;\/div&gt;\n   )\n}\n \nexport default UsersList;\n<\/code><\/pre>\n\n<p>En el bloque de c\u00f3digo anterior, usamos el <a href=\"https:\/\/www.unimedia.tech\/2021\/09\/12\/a-quick-introduction-to-react-hooks\/\">React useEffect Hook<\/a> para obtener la lista de usuarios una vez al cargar. A continuaci\u00f3n, almacenamos los datos recibidos mediante un gancho useState y los asignamos a los componentes de tabla proporcionados por Tailwind CSS. En secciones posteriores, utilizaremos los botones Editar y Eliminar y Crear que hemos creado.<\/p>\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2023\/12\/ACtrUo47r0qFuT3-2Mqmq7OQ8hFdOS41L-IlAjGXz0VoddhFIx_gHY1sIqBiqnJGxxxQmuRI4vDgCTxyHuE8YErffJs9fMknpmbY9m2JOJX0NV7ErqTJu-jN0RQi0p2wqF_4b5h1.png\" alt=\"Aplicaci&#xF3;n React CRUD\"\/><\/figure>\n\n<h3 class=\"wp-block-heading\">CrearUsuario.js<\/h3>\n\n<p>A continuaci\u00f3n, crearemos <em>CreateUser.js<\/em> que nos permitir\u00e1 crear un usuario. <\/p>\n\n<pre class=\"wp-block-code has-small-font-size\"><code>import React, { useState } from \"react\";\n \nfunction CreateUser() {\n  \n   const handleSubmit = event =&gt; {\n     event.preventDefault();\n     var data = {\n       'fname': fname,\n       'lname': lname,\n       'username': username,\n       'email': email,\n       'avatar': avatar,\n     }\n \n     fetch('https:\/\/www.mecallapi.com\/api\/users\/create', {\n       method: 'POST',\n       headers: {\n         Accept: 'application\/form-data',\n         'Content-Type': 'application\/json',\n       },\n       body: JSON.stringify(data),\n     })\n     .then(res =&gt; res.json())\n     .then(\n       (result) =&gt; {\n         alert(result&#91;'message'])\n         if (result&#91;'status'] === 'ok') {\n           window.location.href = '\/';\n         }\n       }\n     )\n   }\n    const &#91;fname, setFname] = useState('');\n   const &#91;lname, setLname] = useState('');\n   const &#91;username, setUsername] = useState('');\n   const &#91;email, setEmail] = useState('');\n   const &#91;avatar, setAvatar] = useState('');\n \n   return (\n       &lt;form class=\"w-full max-w-lg mx-auto my-20\" onSubmit={handleSubmit}&gt;\n       &lt;div class=\"flex flex-wrap mx-3 mb-2\"&gt;\n           &lt;div class=\"w-full md:w-1\/2 px-3 mb-3 md:mb-0\"&gt;\n           &lt;label class=\"block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2\" for=\"grid-first-name\"&gt;\n               First Name\n           &lt;\/label&gt;\n           &lt;input\n           class=\"appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white\" id=\"grid-first-name\"\n           type=\"text\"\n           placeholder=\"First Name\"\n           onChange={(e) =&gt; setFname(e.target.value)}\n           label=\"First Name\"\n           \/&gt;\n              \n          \n           &lt;\/div&gt;\n           &lt;div class=\"w-full md:w-1\/2 px-3\"&gt;\n           &lt;label class=\"block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2\"\n           for=\"grid-last-name\"&gt;\n               Last Name\n           &lt;\/label&gt;\n           &lt;input class=\"appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500\" id=\"grid-last-name\"\n           type=\"text\" placeholder=\"Last Name\"\n           onChange={(e) =&gt; setLname(e.target.value)}\n           label=\"Last Name\"\n           \/&gt;\n           &lt;\/div&gt;\n       &lt;\/div&gt;\n       &lt;div class=\"flex flex-wrap mx-3 mb-2\"&gt;\n           &lt;div class=\"w-full md:w-1\/2 px-3 mb-6 md:mb-0\"&gt;\n               &lt;label class=\"block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2\" for=\"grid-first-name\"&gt;\n                   Email Address\n               &lt;\/label&gt;\n               &lt;input class=\"appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white\" id=\"grid-first-name\"\n               type=\"email\"  placeholder=\"Email address\"\n               onChange={(e) =&gt; setEmail(e.target.value)}\n               label=\"Email\"\n               \/&gt;\n           &lt;\/div&gt;\n           &lt;div class=\"w-full md:w-1\/2 px-3\"&gt;\n           &lt;label class=\"block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2\" for=\"grid-last-name\"&gt;\n               Username\n           &lt;\/label&gt;\n           &lt;input class=\"appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500\" id=\"grid-last-name\"\n           label=\"Username\"\n           onChange={(e) =&gt; setUsername(e.target.value)}\n           type=\"text\" placeholder=\"janeDoe\"\n           \/&gt;\n           &lt;\/div&gt;\n       &lt;\/div&gt;\n       &lt;div class=\"flex flex-wrap mx-3 mb-1\"&gt;\n           &lt;div class=\"w-full px-3\"&gt;\n           &lt;label class=\"block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2\" for=\"grid-image\"&gt;\n               Avatar\n           &lt;\/label&gt;\n           &lt;input class=\"appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white focus:border-gray-500\" id=\"grid-image\" type=\"text\"\n           placeholder=\"Image link\"\n           label=\"Avatar\"\n           onChange={(e) =&gt; setAvatar(e.target.value)}\n           \/&gt;\n           &lt;\/div&gt;\n       &lt;\/div&gt;\n       &lt;button type=\"submit\" class=\"inline-flex items-center ml-8 px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500\"&gt;\n           SUBMIT\n       &lt;\/button&gt;\n      \n       &lt;\/form&gt;\n   )\n}\n \nexport default CreateUser;<\/code><\/pre>\n\n<p>En el bloque de c\u00f3digo anterior, creamos un formulario y agregamos sus valores de entrada a las variables de estado correspondientes utilizando el gancho UseState. A continuaci\u00f3n, enviamos estos valores a la API REST CRUD para crear un usuario. <\/p>\n\n<p>Tambi\u00e9n importaremos y utilizaremos el Componente reci\u00e9n creado en nuestro <em>App.js:<\/em><\/p>\n\n<pre class=\"wp-block-code\"><code>import CreateUser from '.\/CreateUser'\n\u2026\u2026\u2026\u2026\u2026\u2026\u2026.\n&lt;Route path='\/create' element={&lt;CreateUser \/&gt;} \/&gt;<\/code><\/pre>\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2023\/12\/BHR0xJ20o55MFSA_2G1TPsZWM36jiM9wuuEXuFfpWl5uuIIlrQy-X6ir6U2rNLWLLBt8-1XUllJZVy-A625c6gYjDqRn48QwY7WS3oGFyrGVVy0fdCawzfzmPHyuHiTO9YNDUCOd.png\" alt=\"Crear p&#xE1;gina\"\/><\/figure>\n\n<h3 class=\"wp-block-heading\">ActualizarUsuario.js<\/h3>\n\n<p>El siguiente paso es crear un componente <em>UpdateUser.js <\/em>que nos permitir\u00e1 editar con \u00e9xito los usuarios creados.<\/p>\n\n<p>En primer lugar, crearemos una funci\u00f3n updateUser en <em>UsersLists.js<\/em><\/p>\n\n<pre class=\"wp-block-code has-small-font-size\"><code>const UpdateUser = id =&gt; {\n   window.location = '\/update\/'+id\n }\n<\/code><\/pre>\n\n<p class=\"has-small-font-size\">y pasarlo al bot\u00f3n de edici\u00f3n.<\/p>\n\n<pre class=\"wp-block-code\"><code>onClick={() =&gt; UpdateUser(user.id)}<\/code><\/pre>\n\n<p>Ahora, podemos crear nuestro <em>UpdateUser.js<\/em><\/p>\n\n<pre class=\"wp-block-code has-small-font-size\"><code>import React, { useState, useEffect } from \"react\";\nimport { useParams } from 'react-router-dom';\n \nfunction UpdateUser() {\n    const { id } = useParams();\n \n   useEffect(() =&gt; {\n     fetch(\"https:\/\/www.mecallapi.com\/api\/users\/\"+id)\n       .then(res =&gt; res.json())\n       .then(\n         (result) =&gt; {\n           setFname(result.user.fname)\n           setLname(result.user.lname)\n           setUsername(result.user.username)\n           setEmail(result.user.email)\n           setAvatar(result.user.avatar)\n         }\n       )\n   }, &#91;id])\n    const handleSubmit = event =&gt; {\n     event.preventDefault();\n     var data = {\n       'id': id,\n       'fname': fname,\n       'lname': lname,\n       'username': username,\n       'email': email,\n       'avatar': avatar,\n     }\n     fetch('https:\/\/www.mecallapi.com\/api\/users\/update', {\n       method: 'PUT',\n       headers: {\n         Accept: 'application\/form-data',\n         'Content-Type': 'application\/json',\n       },\n       body: JSON.stringify(data),\n     })\n     .then(res =&gt; res.json())\n     .then(\n       (result) =&gt; {\n         alert(result&#91;'message'])\n         if (result&#91;'status'] === 'ok') {\n           window.location.href = '\/';\n         }\n       }\n     )\n   }\n    const &#91;fname, setFname] = useState('');\n   const &#91;lname, setLname] = useState('');\n   const &#91;username, setUsername] = useState('');\n   const &#91;email, setEmail] = useState('');\n   const &#91;avatar, setAvatar] = useState('');\n    return (\n       &lt;form class=\"w-full max-w-lg mx-auto my-20\" onSubmit={handleSubmit}&gt;\n       &lt;div class=\"flex flex-wrap mx-3 mb-2\"&gt;\n           &lt;div class=\"w-full md:w-1\/2 px-3 mb-3 md:mb-0\"&gt;\n           &lt;label class=\"block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2\" for=\"grid-first-name\"&gt;\n               First Name\n           &lt;\/label&gt;\n           &lt;input\n           class=\"appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white\" id=\"grid-first-name\"\n           type=\"text\"\n           value={fname}\n           onChange={(e) =&gt; setFname(e.target.value)}\n           label=\"First Name\"\n           \/&gt;\n              \n          \n           &lt;\/div&gt;\n           &lt;div class=\"w-full md:w-1\/2 px-3\"&gt;\n           &lt;label class=\"block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2\"\n           for=\"grid-last-name\"&gt;\n               Last Name\n           &lt;\/label&gt;\n           &lt;input class=\"appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500\" id=\"grid-last-name\"\n           type=\"text\" value={lname}\n           onChange={(e) =&gt; setLname(e.target.value)}\n           label=\"Last Name\"\n           \/&gt;\n           &lt;\/div&gt;\n       &lt;\/div&gt;\n       &lt;div class=\"flex flex-wrap mx-3 mb-2\"&gt;\n           &lt;div class=\"w-full md:w-1\/2 px-3 mb-6 md:mb-0\"&gt;\n               &lt;label class=\"block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2\" for=\"grid-first-name\"&gt;\n                   Email Address\n               &lt;\/label&gt;\n               &lt;input class=\"appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white\" id=\"grid-first-name\"\n               type=\"email\"  value={email}\n               onChange={(e) =&gt; setEmail(e.target.value)}\n               label=\"Email\"\n               \/&gt;\n           &lt;\/div&gt;\n           &lt;div class=\"w-full md:w-1\/2 px-3\"&gt;\n           &lt;label class=\"block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2\" for=\"grid-last-name\"&gt;\n               Username\n           &lt;\/label&gt;\n           &lt;input class=\"appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500\" id=\"grid-last-name\"\n           label=\"Username\"\n           onChange={(e) =&gt; setUsername(e.target.value)}\n           type=\"text\" value={username}\n           \/&gt;\n           &lt;\/div&gt;\n       &lt;\/div&gt;\n       &lt;div class=\"flex flex-wrap mx-3 mb-1\"&gt;\n           &lt;div class=\"w-full px-3\"&gt;\n           &lt;label class=\"block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2\" for=\"grid-image\"&gt;\n               Avatar\n           &lt;\/label&gt;\n           &lt;input class=\"appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white focus:border-gray-500\" id=\"grid-image\" type=\"text\"\n           value={avatar}\n           label=\"Avatar\"\n           onChange={(e) =&gt; setAvatar(e.target.value)}\n           \/&gt;\n           &lt;\/div&gt;\n       &lt;\/div&gt;\n       &lt;button type=\"submit\" class=\"inline-flex items-center ml-8 px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500\"&gt;\n           Update\n       &lt;\/button&gt;\n      \n       &lt;\/form&gt;\n   )\n}\n \nexport default UpdateUser;\n<\/code><\/pre>\n\n<p>En el fragmento de c\u00f3digo anterior, recuperamos y mostramos el ID de usuario actual del usuario cuyos datos deseamos editar. A continuaci\u00f3n, actualizamos los valores utilizando las entradas del formulario realizadas por el usuario.<\/p>\n\n<p>Tambi\u00e9n importaremos y utilizaremos el Componente reci\u00e9n creado en nuestro <em>App.js:<\/em><\/p>\n\n<pre class=\"wp-block-code has-small-font-size\"><code>import UpdateUser from '.\/UpdateUser'\n\u2026\u2026\u2026\n&lt;Route path='\/update\/:id' element={&lt;UpdateUser \/&gt;}\/&gt;<\/code><\/pre>\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2023\/12\/8Dz8id83eyERq_XDSsnVOimXQ0nTbLqLQrK6rOrAMQLBP65YWuHuHKjip3vllgiGQ96-1gaiqw45Li4OQ1k_1cA-vd1BzTY7a6-oLNaR-xvmcC8jgQPg9mYZ3fIkblzOhs7WxBON.png\" alt=\"P&#xE1;gina de actualizaci&#xF3;n\"\/><\/figure>\n\n<h3 class=\"wp-block-heading\">BORRAR<\/h3>\n\n<p>Por \u00faltimo, activaremos el bot\u00f3n de suprimir. Esto no requiere un nuevo componente en su lugar, estaremos actualizando nuestro Componente UsersList.js. <\/p>\n\n<pre class=\"wp-block-code has-small-font-size\"><code>const DeleteUser = id =&gt; {\n       var data = {\n         'id': id\n       }\n       fetch('https:\/\/www.mecallapi.com\/api\/users\/delete', {\n         method: 'DELETE',\n         headers: {\n           Accept: 'application\/form-data',\n           'Content-Type': 'application\/json',\n         },\n         body: JSON.stringify(data),\n       })\n       .then(res =&gt; res.json())\n       .then(\n         (result) =&gt; {\n           alert(result&#91;'message'])\n           if (result&#91;'status'] === 'ok') {\n               ReadUsers()\n           }\n         }\n       )\n     }\n\n&lt;button onClick={() =&gt; DeleteUser(user.id)} class=\"inline-block text-sm px-4 py-2 leading-none border rounded text-red-800 border-red-600 hover:bg-red-300 hover:text-red-500 mt-4 lg:mt-0\"&gt;DELETE&lt;\/button&gt;<\/code><\/pre>\n\n<h2 class=\"wp-block-heading\">Demo<\/h2>\n\n<figure class=\"wp-block-video\"><video height=\"486\" style=\"aspect-ratio: 1120 \/ 486;\" width=\"1120\" controls=\"\" src=\"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2021\/11\/ReactNODE_CRUD_APP.mp4\"><\/video><\/figure>\n\n<h2 class=\"wp-block-heading\">Resumen<\/h2>\n\n<p>Eso es todo por ahora. En conclusi\u00f3n, aprendemos a usar Node.js para instalar paquetes esenciales para nuestro React. A continuaci\u00f3n, utilizamos React Hooks y React Router para crear y navegar por nuestros componentes. Por \u00faltimo, realizamos interacciones CRUD b\u00e1sicas para crear, leer, actualizar y eliminar datos de usuario. <\/p>\n\n<p>Si est\u00e1s interesado en seguir desarrollando tus habilidades con React y Node js, aqu\u00ed tienes dos tutoriales nuestros que deber\u00edan ayudarte. Una <a href=\"https:\/\/www.unimedia.tech\/2021\/09\/12\/a-quick-introduction-to-react-hooks\/\">r\u00e1pida introducci\u00f3n a React Hooks<\/a> y la <a href=\"https:\/\/www.unimedia.tech\/2021\/08\/17\/stripe-checkout-integration-with-react\/\">integraci\u00f3n de Stripe Checkout con React<\/a>.<\/p>\n\n<p><\/p>\n\n<h2 class=\"wp-block-heading\">Unimedia Technology<\/h2>\n\n<p>En <a href=\"https:\/\/www.unimedia.tech\/\">Unimedia Technology<\/a> contamos con un equipo de<strong><a href=\"https:\/\/www.unimedia.tech\/dedicated-development-teams\/\">Desarrolladores Web<\/a><\/strong> que pueden ayudarte a desarrollar tus Aplicaciones React m\u00e1s complejas.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En este art\u00edculo aprenderemos a crear una aplicaci\u00f3n CRUD sencilla con React.js, Node.js y TailwindCSS. \u00bfQu\u00e9 es una aplicaci\u00f3n CRUD? Una aplicaci\u00f3n CRUD realiza cuatro operaciones b\u00e1sicas: crear, leer, actualizary eliminar. Muchas aplicaciones con las que interact\u00faas a diario realizan estas tareas b\u00e1sicas. Por ejemplo, Instagram. Puedes Crear perfiles y mensajes almacenados en la base [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":6707,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[215,220],"tags":[],"class_list":["post-7242","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-react-technical-guides-es","category-technical-guides-es"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.6 (Yoast SEO v27.1.1) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Construir una simple aplicaci\u00f3n CRUD usando React y Node - Unimedia Technology<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Construir una simple aplicaci\u00f3n CRUD usando React y Node\" \/>\n<meta property=\"og:description\" content=\"En este art\u00edculo aprenderemos a crear una aplicaci\u00f3n CRUD sencilla con React.js, Node.js y TailwindCSS. \u00bfQu\u00e9 es una aplicaci\u00f3n CRUD? Una aplicaci\u00f3n CRUD realiza cuatro operaciones b\u00e1sicas: crear, leer, actualizary eliminar. Muchas aplicaciones con las que interact\u00faas a diario realizan estas tareas b\u00e1sicas. Por ejemplo, Instagram. Puedes Crear perfiles y mensajes almacenados en la base [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/\" \/>\n<meta property=\"og:site_name\" content=\"Unimedia Technology\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.linkedin.com\/company\/unimedia-technology\/\" \/>\n<meta property=\"article:published_time\" content=\"2021-11-30T05:34:40+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-09T12:57:13+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2023\/12\/Blogging-Tips-LinkedIn-Post-Header-3-8.png\" \/>\n\t<meta property=\"og:image:width\" content=\"700\" \/>\n\t<meta property=\"og:image:height\" content=\"400\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Unimedia\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@UnimediaCTO\" \/>\n<meta name=\"twitter:site\" content=\"@UnimediaCTO\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Unimedia\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutos\" \/>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Construir una simple aplicaci\u00f3n CRUD usando React y Node - Unimedia Technology","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/","og_locale":"es_ES","og_type":"article","og_title":"Construir una simple aplicaci\u00f3n CRUD usando React y Node","og_description":"En este art\u00edculo aprenderemos a crear una aplicaci\u00f3n CRUD sencilla con React.js, Node.js y TailwindCSS. \u00bfQu\u00e9 es una aplicaci\u00f3n CRUD? Una aplicaci\u00f3n CRUD realiza cuatro operaciones b\u00e1sicas: crear, leer, actualizary eliminar. Muchas aplicaciones con las que interact\u00faas a diario realizan estas tareas b\u00e1sicas. Por ejemplo, Instagram. Puedes Crear perfiles y mensajes almacenados en la base [&hellip;]","og_url":"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/","og_site_name":"Unimedia Technology","article_publisher":"https:\/\/www.linkedin.com\/company\/unimedia-technology\/","article_published_time":"2021-11-30T05:34:40+00:00","article_modified_time":"2024-01-09T12:57:13+00:00","og_image":[{"width":700,"height":400,"url":"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2023\/12\/Blogging-Tips-LinkedIn-Post-Header-3-8.png","type":"image\/png"}],"author":"Unimedia","twitter_card":"summary_large_image","twitter_creator":"@UnimediaCTO","twitter_site":"@UnimediaCTO","twitter_misc":{"Escrito por":"Unimedia","Tiempo de lectura":"13 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/#article","isPartOf":{"@id":"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/"},"author":{"name":"Unimedia","@id":"https:\/\/www.unimedia.tech\/es\/#\/schema\/person\/3a250aa22526d5c9ff6bc95bb380a5dd"},"headline":"Construir una simple aplicaci\u00f3n CRUD usando React y Node","datePublished":"2021-11-30T05:34:40+00:00","dateModified":"2024-01-09T12:57:13+00:00","mainEntityOfPage":{"@id":"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/"},"wordCount":811,"publisher":{"@id":"https:\/\/www.unimedia.tech\/es\/#organization"},"image":{"@id":"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/#primaryimage"},"thumbnailUrl":"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2023\/12\/Blogging-Tips-LinkedIn-Post-Header-3-8.png","articleSection":["React","Technical Guides"],"inLanguage":"es"},{"@type":"WebPage","@id":"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/","url":"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/","name":"Construir una simple aplicaci\u00f3n CRUD usando React y Node - Unimedia Technology","isPartOf":{"@id":"https:\/\/www.unimedia.tech\/es\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/#primaryimage"},"image":{"@id":"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/#primaryimage"},"thumbnailUrl":"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2023\/12\/Blogging-Tips-LinkedIn-Post-Header-3-8.png","datePublished":"2021-11-30T05:34:40+00:00","dateModified":"2024-01-09T12:57:13+00:00","breadcrumb":{"@id":"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/#primaryimage","url":"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2023\/12\/Blogging-Tips-LinkedIn-Post-Header-3-8.png","contentUrl":"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2023\/12\/Blogging-Tips-LinkedIn-Post-Header-3-8.png","width":700,"height":400,"caption":"react and node"},{"@type":"BreadcrumbList","@id":"https:\/\/www.unimedia.tech\/es\/build-a-simple-crud-app-using-react-and-node\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.unimedia.tech\/es\/"},{"@type":"ListItem","position":2,"name":"Construir una simple aplicaci\u00f3n CRUD usando React y Node"}]},{"@type":"WebSite","@id":"https:\/\/www.unimedia.tech\/es\/#website","url":"https:\/\/www.unimedia.tech\/es\/","name":"Unimedia Technology","description":"Your software development partner","publisher":{"@id":"https:\/\/www.unimedia.tech\/es\/#organization"},"alternateName":"Unimedia Tech","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.unimedia.tech\/es\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.unimedia.tech\/es\/#organization","name":"Unimedia Technology","alternateName":"Unimedia Tech","url":"https:\/\/www.unimedia.tech\/es\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.unimedia.tech\/es\/#\/schema\/logo\/image\/","url":"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2023\/12\/cloud_border-3.png","contentUrl":"https:\/\/www.unimedia.tech\/wp-content\/uploads\/2023\/12\/cloud_border-3.png","width":403,"height":309,"caption":"Unimedia Technology"},"image":{"@id":"https:\/\/www.unimedia.tech\/es\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/company\/unimedia-technology\/","https:\/\/x.com\/UnimediaCTO","https:\/\/www.instagram.com\/unimedia.technology\/"]},{"@type":"Person","@id":"https:\/\/www.unimedia.tech\/es\/#\/schema\/person\/3a250aa22526d5c9ff6bc95bb380a5dd","name":"Unimedia","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.unimedia.tech\/es\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5901fd1c4628e2b48ffd4e47324e8fe0751b39e556a167f078471d4c4bec0f6f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5901fd1c4628e2b48ffd4e47324e8fe0751b39e556a167f078471d4c4bec0f6f?s=96&d=mm&r=g","caption":"Unimedia"}}]}},"_links":{"self":[{"href":"https:\/\/www.unimedia.tech\/es\/wp-json\/wp\/v2\/posts\/7242","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.unimedia.tech\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.unimedia.tech\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.unimedia.tech\/es\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/www.unimedia.tech\/es\/wp-json\/wp\/v2\/comments?post=7242"}],"version-history":[{"count":0,"href":"https:\/\/www.unimedia.tech\/es\/wp-json\/wp\/v2\/posts\/7242\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.unimedia.tech\/es\/wp-json\/wp\/v2\/media\/6707"}],"wp:attachment":[{"href":"https:\/\/www.unimedia.tech\/es\/wp-json\/wp\/v2\/media?parent=7242"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.unimedia.tech\/es\/wp-json\/wp\/v2\/categories?post=7242"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.unimedia.tech\/es\/wp-json\/wp\/v2\/tags?post=7242"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}