diff --git a/04-frameworks/01-react/01-previous/01-concepts/readme.md b/04-frameworks/01-react/01-previous/01-concepts/readme.md
new file mode 100644
index 000000000..73cbd7223
--- /dev/null
+++ b/04-frameworks/01-react/01-previous/01-concepts/readme.md
@@ -0,0 +1,296 @@
+# 01 Previous - Hi React
+
+## Summary
+
+In this example we are going to create a _codesandbox_ to understand the first concepts of React and the main reasons why we need a library like this.
+[Here you have the complete example that we are going to develop.](https://codesandbox.io/p/sandbox/react-concepts-rncyq4)
+
+To begin, we will start from a vanilla JavaScript project and gradually add features that bring us closer to the approach proposed by React. The goal is to see how React solves common web development problems in a more elegant and powerful way.
+
+## Step by step
+
+- Rename the file _index.mjs_ to _index.js_ and update the reference in _index.html_.
+- Comment out all the content of _index.js_.
+- In _index.html_ render a static list of users:
+
+_index.html_
+
+```diff
+
+
+
+ JavaScript Sandbox
+
+
+
+
+-
++
++
Lista de usuarios
++
1955: Rick Sánchez
++
8765: Beth Harmon
++
7562: Farrokh Bulsara
++
+
+
+
+```
+
+This works, but frameworks like React offer us a different approach: they allow us to dynamically transform the DOM in the client. This way, the server only delivers a basic HTML along with a JavaScript file that generates the interface.
+
+We leave the HTML empty and move the list into our _index.js_:
+
+_index.html_
+
+```diff
+
+
+
+ JavaScript Sandbox
+
+
+
+
++
+-
++ `;
+```
+
+Now the content is generated by JavaScript. We can confirm that it’s the JavaScript file that generates the content.
+
+### Components
+
+Let’s start breaking our list into parts.We separate the title and the list:
+
+````diff
+import "./styles.css";
+
++ const Header = () => {
++ return `
+`;
+```
+
+This functions we just created, in React, are components. That is, **in React, components are functions.** For now, these components return a piece of our application, in this case the title and the list, which render something in the DOM.
+
+### Props
+
+Now let’s create a component that renders each user in the DOM. To do this, we’ll create a component (function) that receives a user object with an `id` and `name`:
+
+```diff
+import "./styles.css";
+
+const Header = () => {
+ return `
Lista de usuarios
`;
+};
+
++ const User = (props) => {
++ return `
${props.id}: ${props.name}
`;
++ };
+
+const List = () => {
+ return `
+
++ ${User({id: 1955, name 'Rick Sánchez'})}
++ ${User({id: 8765, name 'Beth Harmon'})}
++ ${User({id: 7562, name 'Farrokh Bulsara'})}
+-
1955: Rick Sánchez
+-
8765: Beth Harmon
+-
7562: Farrokh Bulsara
+
`;
+};
+
+document.getElementById("app").innerHTML = `
+ ${Header()}
+ ${List()}
+`;
+````
+
+In React jargon, the input arguments we pass to components are known as `props`. A bit later we’ll see that in React, the syntax for running a component is very different from this. However, it’s very important to keep in mind that even though the syntax is different, in the end what we’re doing is invoking functions and passing them input arguments.
+
+Let’s get a little closer to what a real application would do and simulate that the data we display in the list comes from an API. For this, let’s create a file _./api.js_.
+
+```js
+export const getUsers = () => [
+ { id: 1955, name: "Rick Sánchez" },
+ { id: 8765, name: "Beth Harmon" },
+ { id: 7562, name: "Farrokh Bulsara" },
+];
+```
+
+When invoking it inside the `List` function, we can directly use a `map` method to execute the `User` function for each element of the array, no matter how many there are.
+
+```diff
++ import { getUsers } from './api';
+import "./styles.css";
+
+const Header = () => {
+ return `
++ ${users.map(user=>User(user)).join('')}
+- ${User({id: 1955, name 'Rick Sánchez'})}
+- ${User({id: 8765, name 'Beth Harmon'})}
+- ${User({id: 7562, name 'Farrokh Bulsara'})}
+
`;
+};
+
+document.getElementById("app").innerHTML = `
+ ${Header()}
+ ${List()}
+`;
+```
+
+In React, however, the `props` argument is a single parameter: an object to which I can pass whatever I want. Let’s adapt the code.
+
+```diff
+import { getUsers } from "./api";
+import "./styles.css";
+
+const Header = () => {
+ return `
Lista de usuarios
`;
+};
+
+- const User = (props) => {
++ const User = ({ user }) => {
+- return `
`;
+};
+
+document.getElementById("app").innerHTML = `
+ ${Header()}
+ ${List()}
+`;
+```
+
+### Reactivity
+
+Let’s try to render a random number for each element, calculated at the moment the component is invoked.
+
+```diff
+const User = ({ user }) => {
++ const randomNumber = Math.random();
+- return `
${user.id}: ${user.name}
`;
++ return `
${user.id}: ${user.name} - ${randomNumber}
`;
+};
+```
+
+If we update it with a setTimeout, we see the value changes in the console, but the interface does not update:
+
+```diff
+const User = ({ user }) => {
+- const randomNumber = Math.random();
++ let randomNumber = Math.random();
++ setTimeout(() => {
++ randomNumber = Math.random();
++ console.log(randomNumber);
++ }, 3000);
+ return `
${user.id}: ${user.name} - ${randomNumber}
`;
+};
+```
+
+Why doesn’t the interface refresh after the three seconds of the setTimeout? Try to think of the answer...
+
+The explanation is simple: functions are executed only once. At that moment they return something that generates a fragment of HTML. That initial result is what gets injected into the DOM and doesn’t change again, even though the internal logic of the function (like the value of `randomNumber`) does get updated later.
+
+If we look at the console, we see that the value of `randomNumber` is indeed recalculated, but the interface doesn’t reflect that change. This happens because the DOM is not automatically linked to the data of our application.
+
+And this is where libraries like React come in. Their main value is that they incorporate reactivity: they allow us to keep the application state and the user interface in sync.
+
+In React, states are the key piece to persist and manage data. Every time a state changes, React re-executes the components that depend on it, ensuring the interface updates and stays aligned with the most recent information.
+
+### Events and persistence
+
+```diff
+const List = () => {
+- const users = getUsers();
++ let users = getUsers();
+
++ const handleClick = () => {
++ alert("button clicked!");
++ users = [...users, { id: 1234, name: "John Doe" }];
++ };
+
+ return `
+
+ ${users.map((user) => User({ user })).join("")}
++
+
`;
+};
+```
+
+The button appears but when clicking it, not even the alert shows up. What’s going on?
+Again, when `List` is executed, the `handleClick` function is created. However, that function doesn’t run until we click the button, and when that happens, the function no longer exists, because the `List` function has already executed and died.
+
+This is another problem React solves, since it allows us to persist data and functions between executions of our components.
+
+To leave the example ready for the next exercise, let’s make the following change:
+
+```diff
++ export default function App() {
++ return `
++ ${Header()}
++ ${List()}
++ `;
++ }
+
++ document.getElementById("app").innerHTML = App();
+- document.getElementById("app").innerHTML = `
+- ${Header()}
+- ${List()}
+- `;
+```
diff --git a/04-frameworks/01-react/01-previous/01-concepts/readme_es.md b/04-frameworks/01-react/01-previous/01-concepts/readme_es.md
new file mode 100644
index 000000000..e1a254256
--- /dev/null
+++ b/04-frameworks/01-react/01-previous/01-concepts/readme_es.md
@@ -0,0 +1,296 @@
+# 01 Previo - Hola React
+
+## Resumen
+
+En este ejemplo vamos a crear un _codesandbox_ para entender los primeros conceptos de React y los motivos principales por los que necesitamos una librería como esta.
+[Aquí tenéis el ejemplo completo que vamos a desarrollar.](https://codesandbox.io/p/sandbox/react-concepts-rncyq4)
+
+Para comenzar, partiremos de un proyecto en vanilla JavaScript e iremos añadiendo poco a poco funcionalidades que nos acerquen al enfoque que propone React. El objetivo es ver cómo React resuelve de forma más elegante y potente problemas comunes del desarrollo web.
+
+## Paso a paso
+
+- Renombramos el archivo _index.mjs_ a _index.js_ y actualizamos la referencia en _index.html_.
+- Comentamos todo el contenido de _index.js_.
+- En el fichero _index.html_ vamos a renderizar de forma estática una lista de usuarios:
+
+_index.html_
+
+```diff
+
+
+
+ JavaScript Sandbox
+
+
+
+
+-
++
++
Lista de usuarios
++
1955: Rick Sánchez
++
8765: Beth Harmon
++
7562: Farrokh Bulsara
++
+
+
+
+```
+
+Esto funciona, pero frameworks como React nos ofrecen un enfoque distinto: permiten transformar dinámicamente el DOM en el cliente. Así, el servidor solo entrega un HTML básico junto con un archivo JavaScript que genera la interfaz.
+
+Dejamos el HTML vacío y movemos la lista a nuestro archivo _index.js_:
+
+_index.html_
+
+```diff
+
+
+
+ JavaScript Sandbox
+
+
+
+
++
+-
++ `;
+```
+
+Ahora el contenido lo genera JavaScript. Comprobamos que es el fichero de JavaScript el que me genera el contenido.
+
+### Componentes
+
+Vamos a ir partiendo nuestra lista en partes. Así, vamos a segregar el header y la lista en dos componentes a parte.
+
+```diff
+import "./styles.css";
+
++ const Header = () => {
++ return `
+`;
+```
+
+A estas funciones que acabamos de crear, en React, las vamos a llamar componentes. Es decir, **en React los componentes son funciones.** Por el momento estos componentes nos devuelven un trocito de nuestra aplicación, en este caso el título y la lista, es decir, renderizan algo en el DOM.
+
+### Props
+
+Vamos a crear ahora un componente que me renderice en el DOM, cada usuario. Para ello vamos a crear un componente (función) que reciba un objeto usuario con un `id` y un `name`:
+
+```diff
+import "./styles.css";
+
+const Header = () => {
+ return `
Lista de usuarios
`;
+};
+
++ const User = (props) => {
++ return `
${props.id}: ${props.name}
`;
++ };
+
+const List = () => {
+ return `
+
++ ${User({id: 1955, name 'Rick Sánchez'})}
++ ${User({id: 8765, name 'Beth Harmon'})}
++ ${User({id: 7562, name 'Farrokh Bulsara'})}
+-
1955: Rick Sánchez
+-
8765: Beth Harmon
+-
7562: Farrokh Bulsara
+
`;
+};
+
+document.getElementById("app").innerHTML = `
+ ${Header()}
+ ${List()}
+`;
+```
+
+En el argot de react los argumentos de entrada que les pasamos a los componentes se les conoce por el nombre de `props`. Un poco más adelante veremos que además, en React, la sintaxis para ejecutar un componente es muy distinta a ésta. Sin embargo, es muy importante tener presente que a pesar de que esta sintaxis sea distinta, al final lo que estamos haciendo es invocar funciones y pasándoles argumentos de entrada.
+
+Vamos a acercarnos un poquito más a lo que haría una aplicación real y a simular que los datos que estamos mostrando por la lista nos llegan de una API. Para ello vamos a crearnos un fichero _./api.js_.
+
+```js
+export const getUsers = () => [
+ { id: 1955, name: "Rick Sánchez" },
+ { id: 8765, name: "Beth Harmon" },
+ { id: 7562, name: "Farrokh Bulsara" },
+];
+```
+
+Al invocarlo dentro de la función `List` podemos usar directamente un método `map` para poder ejecutar la función `User` por cada uno de los elementos del array, sean los que sean.
+
+```diff
++ import { getUsers } from './api';
+import "./styles.css";
+
+const Header = () => {
+ return `
++ ${users.map(user=>User(user)).join('')}
+- ${User({id: 1955, name 'Rick Sánchez'})}
+- ${User({id: 8765, name 'Beth Harmon'})}
+- ${User({id: 7562, name 'Farrokh Bulsara'})}
+
`;
+};
+
+document.getElementById("app").innerHTML = `
+ ${Header()}
+ ${List()}
+`;
+```
+
+En react sin embargo el argumento `props` es un único parámetro, un objeto al que voy a poder pasar todo lo que quiera. Adaptamos el código.
+
+```diff
+import { getUsers } from "./api";
+import "./styles.css";
+
+const Header = () => {
+ return `
Lista de usuarios
`;
+};
+
+- const User = (props) => {
++ const User = ({ user }) => {
+- return `
`;
+};
+
+document.getElementById("app").innerHTML = `
+ ${Header()}
+ ${List()}
+`;
+```
+
+### Reactividad
+
+Vamos a intentar renderizar por cada elemento un número random, que se calcule en el momento en el que se invoque nuestro componente.
+
+```diff
+const User = ({ user }) => {
++ const randomNumber = Math.random();
+- return `
${user.id}: ${user.name}
`;
++ return `
${user.id}: ${user.name} - ${randomNumber}
`;
+};
+```
+
+Si lo actualizamos con un setTimeout, vemos que el valor cambia en consola, pero la interfaz no se actualiza:
+
+```diff
+const User = ({ user }) => {
+- const randomNumber = Math.random();
++ let randomNumber = Math.random();
++ setTimeout(() => {
++ randomNumber = Math.random();
++ console.log(randomNumber);
++ }, 3000);
+ return `
${user.id}: ${user.name} - ${randomNumber}
`;
+};
+```
+
+¿Por qué transcurridos los tres segundos del setTimeout la interfaz de nuestra aplicación no se refresca? Intentad pensar la respuesta...
+
+La explicación es sencilla: las funciones se ejecutan únicamente una vez. En ese momento devuelven un return que genera un fragmento de HTML. Ese resultado inicial es el que se inyecta en el DOM y no vuelve a cambiar, aunque la lógica interna de la función (como el valor de `randomNumber`) sí se modifique posteriormente.
+
+Si observamos la consola, veremos que el valor de `randomNumber` efectivamente se recalcula, pero la interfaz no refleja ese cambio. Esto ocurre porque el DOM no está vinculado de manera automática a los datos de nuestra aplicación.
+
+Y aquí es donde entran en juego librerías como React. Su principal valor es que incorporan reactividad: permiten mantener sincronizados el estado de la aplicación y la interfaz de usuario.
+
+En React, los estados son la pieza clave para persistir y gestionar datos. Cada vez que un estado cambia, React vuelve a ejecutar los componentes que dependen de él, asegurando que la interfaz se actualice y quede alineada con la información más reciente.
+
+### Eventos y persistencia
+
+```diff
+const List = () => {
+- const users = getUsers();
++ let users = getUsers();
+
++ const handleClick = () => {
++ alert("button clicked!");
++ users = [...users, { id: 1234, name: "John Doe" }];
++ };
+
+ return `
+
+ ${users.map((user) => User({ user })).join("")}
++
+
`;
+};
+```
+
+El botón aparece pero al clicar en él, no aparece ni siquiera el alert. ¿Qué está pasando?
+De nuevo, cuando `List` se ejecuta, la función `handleClick` se crea. Sin embargo, esa función no se ejecuta hasta que clicamos en el botón y cuando esto ocurre, la función ya no existe, porque la función `List` se ha ejecutado y ha muerto.
+
+Este es otro de los problemas que va a venir a solucionar React, ya que nos va a permitir, persistir datos, funciones entre ejecución y ejecución de nuestros componentes.
+
+De cara a dejar el ejemplo preparado para el siguiente ejercicio vamos a hacer el siguiente cambio:
+
+```diff
++ export default function App() {
++ return `
++ ${Header()}
++ ${List()}
++ `;
++ }
+
++ document.getElementById("app").innerHTML = App();
+- document.getElementById("app").innerHTML = `
+- ${Header()}
+- ${List()}
+- `;
+```
diff --git a/04-frameworks/01-react/01-previous/02-basic/readme.md b/04-frameworks/01-react/01-previous/02-basic/readme.md
new file mode 100644
index 000000000..069486742
--- /dev/null
+++ b/04-frameworks/01-react/01-previous/02-basic/readme.md
@@ -0,0 +1,217 @@
+# 01 Basic - Hi React
+
+We are going to migrate the JavaScript application from _01-concepts_ ato react. [Here you have the complete example we are going to develop](https://codesandbox.io/p/sandbox/react-basic-h9rhkk) For this, we’ll create a React codesandbox..
+
+We create the same file _./api.js_
+
+```js
+export const getUsers = () => [
+ { id: 1955, name: "Rick Sánchez" },
+ { id: 8765, name: "Beth Harmon" },
+ { id: 7562, name: "Farrokh Bulsara" },
+];
+```
+
+Next, from the example we left ready in _01-concepts_, we are going to copy and paste _index.js_. We are only going to change what each of the components returns. The reason is that in React, components return `jsx` elements, which is nothing more than syntactic sugar for JavaScript.
+
+**We replace string literals with jsx elements in the components:**
+
+For example in the `Header` component:
+
+- In Javascript:
+
+```js
+const Header = () => {
+ return `
`
+};
+```
+
+If we apply the same type of change in the rest of the components, the index.jsx file should look like this:
+
+```jsx
+import React from "react";
+import { getUsers } from "./api";
+import "./styles.css";
+
+const Header = () => {
+ return
+ );
+}
+```
+
+We check that our application renders the list on the screen.
+
+**React syntax**
+In React we are able to use `jsx` syntax when we invoke our components:
+
+```diff
+export default function App() {
+ return (
+
++
++
+- {Header()}
+- {List()}
+
+ );
+}
+```
+
+Also, if we want to pass an argument through props (the input arguments to our component):
+
+```diff
+const List = () => {
+ const users = getUsers();
+- return
{users.map((user) => User({ user }))}
;
++ return
{users.map((user) => )}
;
+};
+```
+
+When doing this, the console will throw an error that appears when we render elements by iterating over a list. As we can see in the trace, it asks us to pass the component a unique `key` value (later on we’ll see why this is necessary):
+
+```diff
+const List = () => {
+ const users = getUsers();
+- return
{users.map((user) => )}
;
++ return
{users.map((user) => )}
;
+};
+```
+
+But as we can see, the `randomNumber` variable is still out of sync with our user interface. This happens because we are not storing that value in state, so React doesn’t know about the change. To make our application reactive, we make the following change:
+
+```diff
+const User = ({ user }) => {
+- let randomNumber = Math.random();
++ const [randomNumber, setRandomNumber] = React.useState(Math.random())
+
+
+setTimeout(() => {
+- randomNumber = Math.random();
++ setRandomNumber(Math.random());
+ console.log(randomNumber);
+}, 3000);
+
+
+ return (
+
+ {user.id}: {user.name} - {randomNumber}
+
+ );
+};
+```
+
+If we look closely, we see that even though it’s a setTimeout (which should execute only once), it’s actually running every three seconds. Why?
+
+In the code, the setTimeout is inside the body of the component. That means every time the component re-renders, React creates a new setTimeout.
+
+When the setTimeout finishes, it calls setRandomNumber, which changes the state. That state change triggers a new render, and in that render a new setTimeout is created again. This creates an infinite loop:
+
+1. Execution/render → creates setTimeout.
+2. SetTimeout → randomNumber changes state.
+3. React detects state change → React re-renders component.
+4. Back to step 1.
+
+The key: it’s not that the setTimeout repeats automatically, but that it gets recreated on every execution.
+
+When we write logic directly inside a React component, that logic will run on every render. This can cause performance issues, application errors, or even infinite loops (like in this setTimeout case, which gets recreated every render).
+
+To control when and under what conditions some code executes, React gives us the useEffect hook, which allows us to manage side effects (like timers, API requests, or event subscriptions) in a controlled way.
+
+Its syntax is:
+
+```jsx
+useEffect(() => {
+ // 👇 Código (efecto) que quieres ejecutar
+}, [dependencias]);
+```
+
+Parameters of useEffect:
+
+- Callback (effect): the function we want to execute.
+- Dependency list: an array that tells React when to re-run the callback.
+
+Examples:
+
+- [] → the effect runs only once, when the component mounts.
+- [state] → the effect runs every time that state changes.
+- undefined → the effect runs on every render.
+
+So, we use `useEffect` with an empty dependency array, because we want the setTimeout to run only once, when the component is created:
+
+```diff
+const User = ({ user }) => {
+const [randomNumber, setRandomNumber] = React.useState(Math.random())
+
++ React.useEffect(()=>{
+ setTimeout(() => {
+ setRandomNumber(Math.random());
+ console.log(randomNumber);
+ }, 3000);
++ },[])
+
+ return (
+
+ {user.id}: {user.name} - {randomNumber}
+
+ );
+};
+```
+
+Now let’s create a button that, when clicked, adds a new element to the list:
+
+```diff
+const List = () => {
+- const users = getUsers();
++ Const [users, setUsers] = React.useState(getUsers());
+
++ const handleClick = () => {
++ setUsers([...users, {id: 1234, name: 'John Doe'}])
++ }
+
+- return return
{users.map((user) => )}
;
++ return (
++
++ {users.map((user) => (
++
++ ))}
++
++
++ );
+};
+```
diff --git a/04-frameworks/01-react/01-previous/02-basic/readme_es.md b/04-frameworks/01-react/01-previous/02-basic/readme_es.md
new file mode 100644
index 000000000..94ee2fedb
--- /dev/null
+++ b/04-frameworks/01-react/01-previous/02-basic/readme_es.md
@@ -0,0 +1,217 @@
+# 01 Basic - Hola React
+
+Vamos a migrar la aplicación en Javascript de _01-concepts_ a react. [Aquí tenéis el ejemplo completo que vamos a desarrollar](https://codesandbox.io/p/sandbox/react-basic-h9rhkk) Para ello vamos a crearnos un codesandbox de react.
+
+Creamos el mismo fichero _./api.js_
+
+```js
+export const getUsers = () => [
+ { id: 1955, name: "Rick Sánchez" },
+ { id: 8765, name: "Beth Harmon" },
+ { id: 7562, name: "Farrokh Bulsara" },
+];
+```
+
+A continuación, desde el ejemplo que hemos dejado preparado en _01-concepts_ vamos a copiar y pegar _index.js_. Vamos a cambiar únicamente lo que devuelve cada uno de los componentes. El motivo es que en react, los componentes devuelven elementos `jsx`, que no es más que azúcar sintáctico de javascript.
+
+**Reemplazamos literales por elementos jsx en los componentes:**
+
+Por ejemplo, en el componente `Header`:
+
+- En código Javascript:
+
+```js
+const Header = () => {
+ return `
`
+};
+```
+
+Si aplicamos el mismo tipo de cambio en el resto de componentes, el fichero _index.jsx_ nos tendría que quedar así:
+
+```jsx
+import React from "react";
+import { getUsers } from "./api";
+import "./styles.css";
+
+const Header = () => {
+ return
+ );
+}
+```
+
+Comprobamos que nuestra aplicación renderiza la lista por la pantalla.
+
+**Sintaxis React**
+En React vamos a poder usar la sintaxis _jsx cuando_ invocamos nuestros componentes:
+
+```diff
+export default function App() {
+ return (
+
++
++
+- {Header()}
+- {List()}
+
+ );
+}
+```
+
+Además, si queremos pasar un argumento por props (argumentos de entrada a nuestro componente):
+
+```diff
+const List = () => {
+ const users = getUsers();
+- return
{users.map((user) => User({ user }))}
;
++ return
{users.map((user) => )}
;
+};
+```
+
+Al hacer esto, la consola nos va a lanzar un error que aparece cuando renderizamos elementos iterando por una lista. Como vemos en la traza, nos pide que le pasemos al componente una key con valor único (ya veremos más adelante a que se debe):
+
+```diff
+const List = () => {
+ const users = getUsers();
+- return
{users.map((user) => )}
;
++ return
{users.map((user) => )}
;
+};
+```
+
+Pero, como estamos viendo la variable `randomNumber` sigue estando desincronizada de nuestra interfaz de usuario. Esto se debe a que no estamos guardando ese valor en un estado, por lo que react no se entera del cambio. Para que nuestra aplicación sea reactiva hacemos el siguiente cambio:
+
+```diff
+const User = ({ user }) => {
+- let randomNumber = Math.random();
++ const [randomNumber, setRandomNumber] = React.useState(Math.random())
+
+
+setTimeout(() => {
+- randomNumber = Math.random();
++ setRandomNumber(Math.random());
+ console.log(randomNumber);
+}, 3000);
+
+
+ return (
+
+ {user.id}: {user.name} - {randomNumber}
+
+ );
+};
+```
+
+Si nos fijamos vemos, que a pesar de que es un setTimeout (debería ejecutarse una sola vez), se está ejecutando cada tres segundos ¿Por qué?
+
+En el código, el setTimeout está dentro del cuerpo del componente. Eso significa que cada vez que el componente se re-ejecuta, React vuelve a crear un nuevo setTimeout.
+
+Cuando el setTimeout se cumple, llama a setRandomNumber, lo cual cambia el estado. Ese cambio de estado provoca un nuevo renderizado, y en ese nuevo renderizado se vuelve a crear otro setTimeout. Así entras en un bucle infinito:
+
+1. Ejecución/render → crea setTimeout.
+2. SetTimeout → randomNumber cambia estado.
+3. React detecta cambio de estado → React ejecuta componente de nuevo.
+4. Vuelve al paso 1.
+
+La clave: no es que el setTimeout se repita automáticamente, sino que se vuelve a crear en cada ejecución.
+
+Cuando escribimos lógica directamente dentro de un componente de React, esa lógica se va a ejecutar en cada renderizado. Esto puede generar problemas de rendimiento, fallos en la aplicación, o incluso bucles infinitos (como en el caso de setTimeout, que se vuelve a crear en cada render).
+
+Para controlar cuándo y con qué condiciones se ejecuta cierto código, React nos proporciona el hook `useEffect`, que nos permite manejar efectos secundarios (side effects), como temporizadores, peticiones a APIs o suscripciones a eventos, de forma controlada.
+
+Su sintaxis es la siguiente:
+
+```jsx
+useEffect(() => {
+ // 👇 Código (efecto) que quieres ejecutar
+}, [dependencias]);
+```
+
+Parámetros de useEffect:
+
+- Callback (efecto): la función que queremos ejecutar.
+- Lista de dependencias: un array que indica cuándo debe volver a ejecutarse ese callback.
+
+Ejemplos:
+
+- [] → el efecto solo se ejecuta una vez, cuando el componente se monta.
+- [estado] → el efecto se ejecuta cada vez que cambia estado.
+- undefined → el efecto se ejecuta en cada renderizado. (evitar)
+
+Así, usamos `useEffect` con un array de dependencias vacío, porque queremos que el `setTimeout` se ejecute una sola vez, cuando se crea el componente:
+
+```diff
+const User = ({ user }) => {
+const [randomNumber, setRandomNumber] = React.useState(Math.random())
+
++ React.useEffect(()=>{
+ setTimeout(() => {
+ setRandomNumber(Math.random());
+ console.log(randomNumber);
+ }, 3000);
++ },[])
+
+ return (
+
+ {user.id}: {user.name} - {randomNumber}
+
+ );
+};
+```
+
+Vamos a crear ahora un button que al clicar, me añada un nuevo elemento a la lista:
+
+```diff
+const List = () => {
+- const users = getUsers();
++ Const [users, setUsers] = React.useState(getUsers());
+
++ const handleClick = () => {
++ setUsers([...users, {id: 1234, name: 'John Doe'}])
++ }
+
+- return return
{users.map((user) => )}
;
++ return (
++
++ {users.map((user) => (
++
++ ))}
++
++
++ );
+};
+```
diff --git a/04-frameworks/01-react/01-previous/readme.md b/04-frameworks/01-react/01-previous/readme.md
deleted file mode 100644
index e69de29bb..000000000
diff --git a/04-frameworks/01-react/01-previous/readme_es.md b/04-frameworks/01-react/01-previous/readme_es.md
deleted file mode 100644
index f5b2f8b53..000000000
--- a/04-frameworks/01-react/01-previous/readme_es.md
+++ /dev/null
@@ -1,185 +0,0 @@
-# 01 Previo - Hola React
-
-## Resumen
-
-En este ejemplo vamos a usar _codesandbox_ para crear nuestro primer proyecto en React.
-
-Puedes encontrar el ejemplo ya implementado en esta URL: https://codesandbox.io/s/strange-tdd-evsp07
-
-## Paso a paso
-
-- Codesandbox es una herramienta que nos permite crear proyectos de prueba en React, Angular, Vue,
- o TS / ES6 plano trabajando directamente en nuestro navegador web.
-
-- Si entramos podemos elegir un nuevo proyecto, vamos a seleccionar React + JS.
-
-- Este proyecto se crea usando una plantilla de _create-react-app_, más adelante sabremos más
- sobre este cli, ahora nos vamos a centrar en que estructura tiene una aplicacíon react.
-
-- Primero vamos a abrir el fichero _index.html_ que se encuentra bajo la carpeta public,
- lo más importante que podemos destacar aquí es el siguiente div:
-
-_./public/index.html_
-
-```html
-
-```
-
-- Ese es el punto de entrada para nuestra aplicación React.
-
-- React es una librería que no está hecha sólo para correr en un navegador web, la podemos
- encontrar también disponible para, por ejemplo, desarrollar aplicaciones móviles con
- _react native_. Nos hace falta una librería intermedia que se encarga de conectar
- React con un navegador web, esta librería es react-dom.
-
-- Es hora de abrir el fichero que está en _./src/index.js_ aquí vemos como referenciamos
- al div root que hemos creado antes, creamos la raíz de la aplicación y la renderizamos, para ello:
-
- - Obtenemos el elemento del dom con el id "root" (el que estaba creado en el HTML principal).
- - Creamos la app React en el elemento root.
- - Empezamos a pintarla (fijate que le pasamos el componente raíz App)
-
-> Ojo esta forma de crear la aplicación React es nueva (desde la versión 18), en versiones anteriores
-> se usaba _React.render()_
-
-_./public/index.js_
-
-```jsx
-import { StrictMode } from "react";
-import { createRoot } from "react-dom/client";
-
-import App from "./App";
-
-const rootElement = document.getElementById("root");
-const root = createRoot(rootElement);
-
-root.render(
-
-
-
-);
-```
-
-> ¿ Qué es React.StrictMode? Es una ayuda para detectar problemas en tiempo de desarrollo,
-> detecta si estamos usando ciclos de vida no seguro de componentes, o apis antiguas,
-> más información: https://en.reactjs.org/docs/strict-mode.html
-
-- Ok, acabamos de instanciar un componente que se llama _App_ ¿Donde podemos encontrar esto?
- debajo de _./src/App.js_ en este componente lo que hacemos es mostrar dos textos
-
-```jsx
-export default function App() {
- return (
-
-
Hello CodeSandbox
-
Start editing to see some magic happen!
-
- );
-}
-```
-
-Si te fijas es un componente de tipo función, que devuelve un elemento con dos hijos (los dos H1)
-
-- Vamos a trabajar un poco más sobre este ejemplo, queremos permitir que el usuario teclee
- un nombre y mostrar este nombre por pantalla.
-
-- Primero nos hace falta guardar el nombre que teclea el usuario en una variable que no
- desaparezca una vez que se ha ejecutado la función, para ello usaremos _react.useState_.
-
-```diff
-export default function App() {
-+ // React.useState returns an array
-+ // item[0] is the getter (returns the username)
-+ // item[1] is the setter (let us update the state)
-+ // That's why we are appliying here destructuring:
-+ const [username, setUsername] = React.useState('No name');
-+
- return (
-
-
Hello CodeSandbox
-
Start editing to see some magic happen!
-
- );
-}
-```
-
-¿Qué diferencia tiene esto con usar una variable? Si usaramos una variable tal cual
-esta se detruiría al terminar la función y se volvería a crear cuando volvieramos a ejecutar
-la función, al usar _React.useState_ esta función guarda "en un cajón desastre" el valor que
-se estaba editando y lo vuelve a inyectar cuando se vuelve a llamar a la función.
-
-- Vamos a mostrar el nombre del usuario que está guardado en ese _state_. Esto lo veremos más en
- detalle luego, pero abramos boca en este ejemplo, en el código que vemos que parece HTML,
- podemos escribir Javascript, ¿Cómo? Encerrandolo entre llaves:
-
-```diff
- return (
-
--
Hello CodeSandbox
-+
{username}
-
Start editing to see some magic happen!
-
- );
-```
-
-Aquí estamos diciendo en el _h1_, que ejecuta el código javascript que evalua la variable
-_username_
-
-- Ahora queremos ir un paso más alla, queremos crear un input que permita al usuario
- editar el nombre del usuario, si ponemos algo así como:
-
-```diff
- return (
-
-
{username}
--
Start editing to see some magic happen!
-+
-
- );
-```
-
-- Podemos ver como aparece el nombre, pero y si intentamos editar, oye resulta que no se actualiza
- esto ¿Por qué? Tenemos que recordar ahora como funcionaba el flujo undireccional, me llegan los
- datos, el input dispara un rerender (repintado)y vuelve a leer el del valor de la variable.
-
-- El input nos expone un evento, _onChange_ que recibe un parametro estandar del _dom_
- accediente a _e.target.value_ tenemos el nuevo valor.
-
-- Podríamos ahora estar tentados a hacer algo así (OJO esto está mal):
-
-```diff
- return (
-
-
{username}
- username = e.target.value}
- >
-
- );
-```
-
-- ¿Qué pasa con esto?
-
- - Primero que no debemos de mutar la variable _username_, esa variable
- para nosotros es de sólo lectura.
-
- - Segundo aunque la mutaramos, al volver a repintarse el componente este valor
- se pierde.
-
-- ¿Qué podemos hacer? Utilizar _setUsername_
-
-```diff
- return (
-
- );
-```
-
-- ¡ Ahora si que funciona! _setUsername_ se encarga de enviar la petición a un sitio que
- seguirá viviendo aunque la función termina, cuando _setState_ se vuelva a invocar
- recupera la información y tendremos nuestro dato disponible.
diff --git a/04-frameworks/01-react/02-base/01-create-react-app/readme.md b/04-frameworks/01-react/02-base/01-create-react-app/readme.md
deleted file mode 100644
index 28562cc61..000000000
--- a/04-frameworks/01-react/02-base/01-create-react-app/readme.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Create React app
-
-To create such an application
-
-https://create-react-app.dev/
-
-````bash
-npx create-react-app my-app
-```
-
-How to upgrade
-
-````bash
-npm install react-scripts@latest
-```
-
-Discuss what _npx_ is and why not _npm install create-react-app -g_
-
-Comment on structure, and comment on how to create _typescript_ project
-
-npx create-react-app my-app --template typescript
-
-And add _TypeScript_ support afterwards
-
-https://create-react-app.dev/docs/adding-typescript
-
-Comment eject and you won't see what's going on.
-
-https://create-react-app.dev/docs/available-scripts/#npm-run-eject
-
-And more fumada customizing and making your template
-
-https://auth0.com/blog/how-to-configure-create-react-app/
diff --git a/04-frameworks/01-react/02-base/01-create-react-app/readme_es.md b/04-frameworks/01-react/02-base/01-create-react-app/readme_es.md
deleted file mode 100644
index 61abf417b..000000000
--- a/04-frameworks/01-react/02-base/01-create-react-app/readme_es.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# Create React app
-
-Para crear una aplicación de este tipo
-
-https://create-react-app.dev/
-
-```bash
-npx create-react-app my-app
-```
-
-Si te da algún problema de versión antigua, prueba a borrar la caché de _npx_
-
-```bash
-sudo npx clear-npx-cache
-```
-
-Si un día necesitas hacer un upgrade de un proyecto existente, lo puedes hacer ejecutando el siguiente comando:
-
-```bash
-npm install react-scripts@latest
-```
-
-Utilizamos _npx_ para traernos siempre la última versión de _create-react-app_. Si lo hicieramos con _npm install create-react-app -g_,
-nos instalaría la versión actual en nuestra máquina de forma global, y si creamos una aplicación en un tiempo no utilizaría la última versión.
-
-Para crear un proyecto con soporte para _typescript_:
-
-```bash
-npx create-react-app my-app --template typescript
-```
-
-O añadir soporte a _TypeScript_ después:
-
-https://create-react-app.dev/docs/adding-typescript
-
-Podemos hacer `eject` de nuestro proyecto y tener acceso directo a la configuración (por ejemplo, de _webpack_):
-
-https://create-react-app.dev/docs/available-scripts/#npm-run-eject
-
-Podemos comprobar abriendo la configuración de _webpack_ que es inmanejable.
-
-Y más fumada customizando y haciendo tu plantilla
-
-https://auth0.com/blog/how-to-configure-create-react-app/
diff --git a/04-frameworks/01-react/02-base/01-vite-boiler/README.md b/04-frameworks/01-react/02-base/01-vite-boiler/README.md
new file mode 100644
index 000000000..90fb0f957
--- /dev/null
+++ b/04-frameworks/01-react/02-base/01-vite-boiler/README.md
@@ -0,0 +1,22 @@
+## 01 Vite boilerplate
+
+## Summary
+
+In this example there is a vite boilerplate set up with Typescript support, just in the step before
+to adding React support.
+
+It is based on the Vite examples.
+
+This example is the only one that doesn't have a step-by-step (if you need guidance, you can go to the
+vite examples you'll find in this repository).
+
+Highlights:
+
+- Added TypeScript as a local dev dependency.
+- Switched project to use ES Modules in package.json.
+- Created a `tsconfig.json` with a minimal configuration.
+- Vite uses esbuild for transpilation (fast, no type checking).
+- Enabled `isolatedModules` and `useDefineForClassFields` for `esbuild`compatibility.
+
+In the following example we will take this as a starting point and we will go step by step adding
+support for React.
diff --git a/04-frameworks/01-react/02-base/03-webpack-react/src/index.html b/04-frameworks/01-react/02-base/01-vite-boiler/index.html
similarity index 55%
rename from 04-frameworks/01-react/02-base/03-webpack-react/src/index.html
rename to 04-frameworks/01-react/02-base/01-vite-boiler/index.html
index a3d74b719..dd5f1546a 100644
--- a/04-frameworks/01-react/02-base/03-webpack-react/src/index.html
+++ b/04-frameworks/01-react/02-base/01-vite-boiler/index.html
@@ -1,12 +1,12 @@
-
-
-
- My App Example
+
+
+
+
diff --git a/04-frameworks/01-react/02-base/01-vite-boiler/package.json b/04-frameworks/01-react/02-base/01-vite-boiler/package.json
new file mode 100644
index 000000000..dfcbe9038
--- /dev/null
+++ b/04-frameworks/01-react/02-base/01-vite-boiler/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "hello-vite",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "start": "vite --host",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "devDependencies": {
+ "typescript": "^5.9.2",
+ "vite": "^7.1.3",
+ "vite-plugin-checker": "^0.10.2"
+ }
+}
diff --git a/04-frameworks/01-react/02-base/01-vite-boiler/readme_es.md b/04-frameworks/01-react/02-base/01-vite-boiler/readme_es.md
new file mode 100644
index 000000000..2104339e9
--- /dev/null
+++ b/04-frameworks/01-react/02-base/01-vite-boiler/readme_es.md
@@ -0,0 +1,22 @@
+## 01 Vite boilerplate
+
+## Resumen
+
+En este ejemplo desarrollamos un boilerplate de Vite configurado con soporte para TypeScript, justo en el paso previo
+a añadir soporte para React.
+
+Está basado en los ejemplos de Vite.
+
+Este ejemplo es el único que no tiene una guía paso a paso (si necesitas orientación, puedes consultar los
+ejemplos de Vite que encontrarás en este repositorio).
+
+Puntos destacados:
+
+- Se agregó TypeScript como dependencia de desarrollo local.
+- Se cambió el proyecto para usar ES Modules `package.json`.
+- Se creó un `tsconfig.json` con una configuración mínima.
+- Vite utiliza esbuild para la transpilación (rápido, sin comprobación de tipos).
+- Se habilitó `isolatedModules` y `useDefineForClassFields` para que sea compatible con `esbuild`.
+
+En el siguiente ejemplo tomaremos este como punto de partida y, paso a paso, añadiremos
+soporte para React.
diff --git a/04-frameworks/01-react/02-base/01-vite-boiler/src/index.ts b/04-frameworks/01-react/02-base/01-vite-boiler/src/index.ts
new file mode 100644
index 000000000..f69b4850f
--- /dev/null
+++ b/04-frameworks/01-react/02-base/01-vite-boiler/src/index.ts
@@ -0,0 +1 @@
+console.log("Vite-boiler-plate");
diff --git a/04-frameworks/01-react/02-base/01-vite-boiler/tsconfig.json b/04-frameworks/01-react/02-base/01-vite-boiler/tsconfig.json
new file mode 100644
index 000000000..6414575cc
--- /dev/null
+++ b/04-frameworks/01-react/02-base/01-vite-boiler/tsconfig.json
@@ -0,0 +1,18 @@
+{
+ "compilerOptions": {
+ "esModuleInterop": true,
+ "isolatedModules": true,
+ "lib": ["ESNext", "DOM"],
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "noEmit": true,
+ "noImplicitAny": false,
+ "noImplicitReturns": true,
+ "resolveJsonModule": true,
+ "skipLibCheck": true,
+ "sourceMap": true,
+ "target": "ESNext",
+ "useDefineForClassFields": true
+ },
+ "include": ["src"]
+}
diff --git a/04-frameworks/01-react/02-base/01-vite-boiler/vite.config.ts b/04-frameworks/01-react/02-base/01-vite-boiler/vite.config.ts
new file mode 100644
index 000000000..5bfe487c0
--- /dev/null
+++ b/04-frameworks/01-react/02-base/01-vite-boiler/vite.config.ts
@@ -0,0 +1,6 @@
+import { defineConfig } from "vite";
+import checker from "vite-plugin-checker";
+
+export default defineConfig({
+ plugins: [checker({ typescript: true })],
+});
diff --git a/04-frameworks/01-react/02-base/05-list-refactor/src/index.html b/04-frameworks/01-react/02-base/02-vite-react/index.html
similarity index 55%
rename from 04-frameworks/01-react/02-base/05-list-refactor/src/index.html
rename to 04-frameworks/01-react/02-base/02-vite-react/index.html
index a3d74b719..050566921 100644
--- a/04-frameworks/01-react/02-base/05-list-refactor/src/index.html
+++ b/04-frameworks/01-react/02-base/02-vite-react/index.html
@@ -1,12 +1,13 @@
-
-
-
- My App Example
+
+
+ React App
+
+
diff --git a/04-frameworks/01-react/02-base/02-vite-react/package.json b/04-frameworks/01-react/02-base/02-vite-react/package.json
new file mode 100644
index 000000000..9ee970f00
--- /dev/null
+++ b/04-frameworks/01-react/02-base/02-vite-react/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "hello-vite",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "start": "vite --host",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "devDependencies": {
+ "@types/react": "^19.1.8",
+ "@types/react-dom": "^19.1.6",
+ "@vitejs/plugin-react": "^4.6.0",
+ "typescript": "^5.8.3",
+ "vite": "^7.0.4",
+ "vite-plugin-checker": "^0.10.0"
+ },
+ "dependencies": {
+ "react": "^19.1.0",
+ "react-dom": "^19.1.0"
+ }
+}
diff --git a/04-frameworks/01-react/02-base/02-vite-react/readme.md b/04-frameworks/01-react/02-base/02-vite-react/readme.md
new file mode 100644
index 000000000..4842fdc1c
--- /dev/null
+++ b/04-frameworks/01-react/02-base/02-vite-react/readme.md
@@ -0,0 +1,98 @@
+# 02 Vite boilerplate - React
+
+## Summary
+
+This example takes the _01-vite-boiler_ example as a starting point.
+
+We will go step by step adding the necessary configuration so that we integrate
+**React** into our build process.
+
+# Step by Step
+
+- First we copy the previous example, and do a _npm install_
+
+```bash
+npm install
+```
+
+- Next, install `react` and `react-dom` dependencies:
+
+```bash
+npm install react react-dom --save
+```
+
+- Install types for `react` y `react-dom` ad dev dependencies:
+
+```bash
+npm install @types/react @types/react-dom -D
+```
+
+- Now open `tsconfig.json` file and set following compiler option to support `jsx` notation in our TypeScript files:
+
+_tsconfig.json_
+
+```diff
+ "compilerOptions": {
+ "esModuleInterop": true,
+ "isolatedModules": true,
++ "jsx": "react-jsx",
+ "lib": ["ESNext", "DOM"],
+ "module": "ESNext",
+```
+
+⚡ `jsx` is a JavaScript syntax extension that will allow us to write HTML-in-JS and is typically used by React components.
+
+- In order to make `vite` fully support `jsx` syntax (among other things) we will add a plugin, otherwise, `esbuild` won't be able to transpile our `react` source files written in `jsx` syntax:
+
+```bash
+npm install @vitejs/plugin-react --save-dev
+```
+
+- Finally, let's modify `vite.config.ts` to add the newly installed plugin:
+
+_vite.config.ts_
+
+```diff
+ import { defineConfig } from "vite";
+ import checker from "vite-plugin-checker";
++ import react from "@vitejs/plugin-react";
+
+ export default defineConfig({
+- plugins: [checker({ typescript: true })],
++ plugins: [checker({ typescript: true }), react()],
+ });
+
+```
+
+- Let's create our first React component.
+
+_./src/app.tsx_
+
+```tsx
+import React from "react";
+
+export const App = () => {
+ return
Hello React !!
;
+};
+```
+
+Lets update our _./src/index.ts_ to _./src/index.tsx_. We also adjust in the _./index.html_ file.
+
+- It's time to instantiate that main component, to be able to integrate it with the browser we have to make use of _createRoot_.
+
+```tsx
+import React from "react";
+import { createRoot } from "react-dom/client";
+import { App } from "./app";
+
+const rootElement = document.getElementById("root");
+const root = createRoot(rootElement);
+
+root.render();
+```
+
+- Let's check that things are working as expected:
+
+```bash
+npm start
+```
diff --git a/04-frameworks/01-react/02-base/02-vite-react/readme_es.md b/04-frameworks/01-react/02-base/02-vite-react/readme_es.md
new file mode 100644
index 000000000..46ce283a8
--- /dev/null
+++ b/04-frameworks/01-react/02-base/02-vite-react/readme_es.md
@@ -0,0 +1,97 @@
+# 02 Vite boilerplate - React
+
+## Resumen
+
+Este ejemplo parte desde el ejemplo _01-vite-boiler_.
+
+Vamos a ir paso a paso, añadiendo la configuración necesaria para integrar **React**.
+
+# Paso a paso
+
+- Antes que nada nos instalamos todos los paquetes necesarios del boilerplate ejecutando _npm install_
+
+```bash
+npm install
+```
+
+- A continuación instalamos `react` y `react-dom` como dependencias:
+
+```bash
+npm install react react-dom --save
+```
+
+- A continuación instalamos los tipos de las librerías `react` y `react-dom` como dependencias de desarrollo:
+
+```bash
+npm install @types/react @types/react-dom -D
+```
+
+- Para hacer que TS entienda la notación `jsx` añadimos lo siguiente en el fichero `tsconfig.json`:
+
+_tsconfig.json_
+
+```diff
+ "compilerOptions": {
+ "esModuleInterop": true,
+ "isolatedModules": true,
++ "jsx": "react-jsx",
+ "lib": ["ESNext", "DOM"],
+ "module": "ESNext",
+```
+
+⚡ `jsx` es azúcar sintáctico que permite escribir HTML-in-JS. Esta sintaxis es la que vamos a usar con los componentes de React.
+
+- Para hacer que `vite` soporte la sintaxis `jsx` (y otras cosas) tenemos que añadir un plugin, sino, `esbuild` no será capaz de transpilar nuestros ficheros de `react`, escritos en formato en `jsx`:
+
+```bash
+npm install @vitejs/plugin-react --save-dev
+```
+
+- Finalmente, modificamos `vite.config.ts` añadiendo nuestro plugin:
+
+_vite.config.ts_
+
+```diff
+ import { defineConfig } from "vite";
+ import checker from "vite-plugin-checker";
++ import react from "@vitejs/plugin-react";
+
+ export default defineConfig({
+- plugins: [checker({ typescript: true })],
++ plugins: [checker({ typescript: true }), react()],
+ });
+
+```
+
+- Creemos ahora nuestro primer componente
+
+_./src/app.tsx_
+
+```tsx
+import React from "react";
+
+export const App = () => {
+ return
Hello React !!
;
+};
+```
+
+Actualizamos _./src/index.ts_ a _./src/index.tsx_. Ajustamos la extensión también en el fichero _./index.html_.
+
+- Vamos a usar el componente que acabamos de crear. Para poder integrar ese componente (y el resto de la aplicación) en nuestro html, hacemos uso de _createRoot_.
+
+```tsx
+import React from "react";
+import { createRoot } from "react-dom/client";
+import { App } from "./app";
+
+const rootElement = document.getElementById("root");
+const root = createRoot(rootElement);
+
+root.render();
+```
+
+- Comprobamos que todo funciona
+
+```bash
+npm start
+```
diff --git a/04-frameworks/01-react/02-base/03-webpack-react/src/app.tsx b/04-frameworks/01-react/02-base/02-vite-react/src/app.tsx
similarity index 100%
rename from 04-frameworks/01-react/02-base/03-webpack-react/src/app.tsx
rename to 04-frameworks/01-react/02-base/02-vite-react/src/app.tsx
diff --git a/04-frameworks/01-react/02-base/05-list-refactor/src/index.tsx b/04-frameworks/01-react/02-base/02-vite-react/src/index.tsx
similarity index 58%
rename from 04-frameworks/01-react/02-base/05-list-refactor/src/index.tsx
rename to 04-frameworks/01-react/02-base/02-vite-react/src/index.tsx
index 7e439b87e..f323553ef 100644
--- a/04-frameworks/01-react/02-base/05-list-refactor/src/index.tsx
+++ b/04-frameworks/01-react/02-base/02-vite-react/src/index.tsx
@@ -2,7 +2,7 @@ import React from "react";
import { createRoot } from "react-dom/client";
import { App } from "./app";
-const container = document.getElementById("root");
-const root = createRoot(container);
+const rootElement = document.getElementById("root");
+const root = createRoot(rootElement);
root.render();
diff --git a/04-frameworks/01-react/02-base/02-vite-react/tsconfig.json b/04-frameworks/01-react/02-base/02-vite-react/tsconfig.json
new file mode 100644
index 000000000..a057cea1d
--- /dev/null
+++ b/04-frameworks/01-react/02-base/02-vite-react/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "compilerOptions": {
+ "esModuleInterop": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "lib": ["ESNext", "DOM"],
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "noEmit": true,
+ "noImplicitAny": false,
+ "noImplicitReturns": true,
+ "resolveJsonModule": true,
+ "skipLibCheck": true,
+ "sourceMap": true,
+ "target": "ESNext",
+ "useDefineForClassFields": true
+ },
+ "include": ["src"]
+}
diff --git a/04-frameworks/01-react/02-base/02-vite-react/vite.config.ts b/04-frameworks/01-react/02-base/02-vite-react/vite.config.ts
new file mode 100644
index 000000000..a0024d88e
--- /dev/null
+++ b/04-frameworks/01-react/02-base/02-vite-react/vite.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from "vite";
+import checker from "vite-plugin-checker";
+import react from "@vitejs/plugin-react";
+
+export default defineConfig({
+ plugins: [checker({ typescript: true }), react()],
+});
diff --git a/04-frameworks/01-react/02-base/02-webpack-boiler/.babelrc b/04-frameworks/01-react/02-base/02-webpack-boiler/.babelrc
deleted file mode 100644
index 3313ff9ef..000000000
--- a/04-frameworks/01-react/02-base/02-webpack-boiler/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@babel/preset-env", "@babel/preset-typescript"]
-}
diff --git a/04-frameworks/01-react/02-base/02-webpack-boiler/package.json b/04-frameworks/01-react/02-base/02-webpack-boiler/package.json
deleted file mode 100644
index 9b1b0de5c..000000000
--- a/04-frameworks/01-react/02-base/02-webpack-boiler/package.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "name": "react-example",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "start": "run-p -l type-check:watch start:dev",
- "type-check": "tsc --noEmit",
- "type-check:watch": "npm run type-check -- --watch",
- "start:dev": "webpack-dev-server --mode development --open",
- "build": "rimraf dist && webpack --mode development"
- },
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "@babel/cli": "^7.17.10",
- "@babel/core": "^7.17.10",
- "@babel/preset-env": "^7.17.10",
- "@babel/preset-typescript": "^7.16.7",
- "babel-loader": "^8.2.5",
- "css-loader": "^6.7.1",
- "html-loader": "^3.1.0",
- "html-webpack-plugin": "^5.5.0",
- "npm-run-all": "^4.1.5",
- "rimraf": "^3.0.2",
- "style-loader": "^3.3.1",
- "typescript": "^4.6.4",
- "webpack": "^5.72.1",
- "webpack-cli": "^4.9.2",
- "webpack-dev-server": "^4.9.0"
- }
-}
diff --git a/04-frameworks/01-react/02-base/02-webpack-boiler/readme.md b/04-frameworks/01-react/02-base/02-webpack-boiler/readme.md
deleted file mode 100644
index 5fe86d280..000000000
--- a/04-frameworks/01-react/02-base/02-webpack-boiler/readme.md
+++ /dev/null
@@ -1,20 +0,0 @@
-## 02 Web Boiler plate
-
-## Summary
-
-In this example there is a webpack boiler plate set up with Typescript support, just in the step before
-to adding React support.
-
-It is based on the Webpack examples.
-
-This example is the only one that doesn't have a step-by-step (if you need guidance, you can go to the
-webpack examples you'll find in this repository).
-
-Highlights:
-
-- The webpackconfig has the src folder configured, and the loaders to handle typescript.
-- We have babel and typescript configuration files.
-- We do the transpilation using babel.
-
-In the following example we will take this as a starting point and we will go step by step adding
-support for React.
diff --git a/04-frameworks/01-react/02-base/02-webpack-boiler/readme_es.md b/04-frameworks/01-react/02-base/02-webpack-boiler/readme_es.md
deleted file mode 100644
index abab80d66..000000000
--- a/04-frameworks/01-react/02-base/02-webpack-boiler/readme_es.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# 02 Web Boiler plate
-
-## Resumen
-
-En este ejemplo hay montado un boiler plate en webpack con soporte a Typescript, justo en el paso previo
-a añadirle soporte a React.
-
-Está basado en los ejemplos de Webpack.
-
-Este ejemplo es el único que no tiene un paso a paso (si necesitas guía puedes ir a los ejemplos
-de webpack que encontrarás en este repositorio).
-
-A destacar:
-
-- El webpackconfig tiene configurada la carpeta src, y los loaders para manejar typescript.
-- Tenemos ficheros de configuracion de babel y typescript.
-- Hacemos la transpilación utlizando babel.
-
-En el siguiente ejemplo tomaremos este como punto de partida y si iremos paso a paso añadiendo
-soporte a React.
diff --git a/04-frameworks/01-react/02-base/02-webpack-boiler/src/index.html b/04-frameworks/01-react/02-base/02-webpack-boiler/src/index.html
deleted file mode 100644
index 26e6c384d..000000000
--- a/04-frameworks/01-react/02-base/02-webpack-boiler/src/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
- My App Example
-
-
-
Hello World !
-
-
diff --git a/04-frameworks/01-react/02-base/02-webpack-boiler/src/index.tsx b/04-frameworks/01-react/02-base/02-webpack-boiler/src/index.tsx
deleted file mode 100644
index 8e1bb81b1..000000000
--- a/04-frameworks/01-react/02-base/02-webpack-boiler/src/index.tsx
+++ /dev/null
@@ -1 +0,0 @@
-console.log("Hello from JS");
diff --git a/04-frameworks/01-react/02-base/02-webpack-boiler/src/styles.css b/04-frameworks/01-react/02-base/02-webpack-boiler/src/styles.css
deleted file mode 100644
index 74dc08fbb..000000000
--- a/04-frameworks/01-react/02-base/02-webpack-boiler/src/styles.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.my-text {
- color: blue;
-}
diff --git a/04-frameworks/01-react/02-base/02-webpack-boiler/tsconfig.json b/04-frameworks/01-react/02-base/02-webpack-boiler/tsconfig.json
deleted file mode 100644
index 3312b5f1e..000000000
--- a/04-frameworks/01-react/02-base/02-webpack-boiler/tsconfig.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "compilerOptions": {
- "target": "es6",
- "module": "es6",
- "moduleResolution": "node",
- "declaration": false,
- "noImplicitAny": false,
- "allowSyntheticDefaultImports": true,
- "sourceMap": true,
- "jsx": "react",
- "noLib": false,
- "suppressImplicitAnyIndexErrors": true,
- "skipLibCheck": true,
- "esModuleInterop": true
- },
- "include": ["src/**/*"],
- "exclude": ["node_modules"]
-}
diff --git a/04-frameworks/01-react/02-base/02-webpack-boiler/webpack.config.js b/04-frameworks/01-react/02-base/02-webpack-boiler/webpack.config.js
deleted file mode 100644
index 326060f82..000000000
--- a/04-frameworks/01-react/02-base/02-webpack-boiler/webpack.config.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const HtmlWebpackPlugin = require("html-webpack-plugin");
-const path = require("path");
-const basePath = __dirname;
-
-module.exports = {
- context: path.join(basePath, "src"),
- resolve: {
- extensions: [".js", ".ts", ".tsx"],
- },
- entry: {
- app: ["./index.tsx", "./styles.css"],
- },
- devtool: "eval-source-map",
- stats: "errors-only",
- output: {
- filename: "[name].[chunkhash].js",
- },
- module: {
- rules: [
- {
- test: /\.tsx?$/,
- exclude: /node_modules/,
- loader: "babel-loader",
- },
- {
- test: /\.(png|jpg)$/,
- type: "asset/resource",
- },
- {
- test: /\.html$/,
- loader: "html-loader",
- },
- {
- test: /\.css$/,
- exclude: /node_modules/,
- use: [
- {
- loader: "style-loader",
- },
- {
- loader: "css-loader",
- },
- ],
- },
- ],
- },
- plugins: [
- //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin
- new HtmlWebpackPlugin({
- filename: "index.html", //Name of file in ./dist/
- template: "index.html", //Name of template in ./src
- }),
- ],
-};
diff --git a/04-frameworks/01-react/02-base/04-list-users/src/index.html b/04-frameworks/01-react/02-base/03-list-users/index.html
similarity index 55%
rename from 04-frameworks/01-react/02-base/04-list-users/src/index.html
rename to 04-frameworks/01-react/02-base/03-list-users/index.html
index a3d74b719..050566921 100644
--- a/04-frameworks/01-react/02-base/04-list-users/src/index.html
+++ b/04-frameworks/01-react/02-base/03-list-users/index.html
@@ -1,12 +1,13 @@
-
-
-
- My App Example
+
+
+ React App
+
+
diff --git a/04-frameworks/01-react/02-base/03-list-users/package.json b/04-frameworks/01-react/02-base/03-list-users/package.json
new file mode 100644
index 000000000..9f55e25d6
--- /dev/null
+++ b/04-frameworks/01-react/02-base/03-list-users/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "hello-vite",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "start": "vite --host",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "devDependencies": {
+ "@types/react": "^19.1.12",
+ "@types/react-dom": "^19.1.9",
+ "@vitejs/plugin-react": "^4.6.0",
+ "typescript": "^5.8.3",
+ "vite": "^7.0.4",
+ "vite-plugin-checker": "^0.10.0"
+ },
+ "dependencies": {
+ "react": "^19.1.0",
+ "react-dom": "^19.1.0"
+ }
+}
diff --git a/04-frameworks/01-react/02-base/04-list-users/readme.md b/04-frameworks/01-react/02-base/03-list-users/readme.md
similarity index 91%
rename from 04-frameworks/01-react/02-base/04-list-users/readme.md
rename to 04-frameworks/01-react/02-base/03-list-users/readme.md
index 33de240fe..b7aafc5d0 100644
--- a/04-frameworks/01-react/02-base/04-list-users/readme.md
+++ b/04-frameworks/01-react/02-base/03-list-users/readme.md
@@ -1,8 +1,8 @@
-# 04 List Users
+# 03 List Users
## Summary
-This example takes the _03-webpack-react_ example as a starting point.
+This example takes the _02-vite-react_ example as a starting point.
We're going to ask the Github API for the list of members that belong to an
organisation and display it on the screen.
@@ -115,12 +115,9 @@ export const App = () => {
With these lines of code, we are iterating through the array of members and creating a span element for each entry,
to take into account:
-- key: when we create elements dynamically, we need to add a unique key to them (so React can optimise the rendering).
- the rendering).
-
+- key: when we create elements dynamically, we need to add a unique key to them (so React can optimize the rendering).
- Member Login: we read the value of the current array element and display the login field.
-
-- Now that we see that it works we are going to fit this in a grid, let's define some gobal styles
+- Now that we see that it works we are going to fit this in a grid, let's define some global styles
(check [CSS modules example](https://github.com/Lemoncode/master-frontend-lemoncode/tree/master/03-bundling/01-webpack/12-css-modules), to learn how to configure component isolated CSS)
_./src/styles.css_
@@ -150,6 +147,17 @@ body {
}
```
+In order to be able to use our styles, we must import them into our project:
+
+\__./src/index.tsx_
+
+```diff
+import React from "react";
+import { createRoot } from "react-dom/client";
+import { App } from "./app";
++ import "./styles.css";
+```
+
- And let's integrate it in our app component:
_./src/app.tsx_
@@ -228,6 +236,8 @@ _./src/app.tsx_
}, []);
```
+A little bit down the module we will see how react 19 brings a specific hook which is ideal for asynchronous operations like data fetching.
+
What are we doing here? We are making a call to the Github REST API, this api is asynchronous (hence why we use
promises), first we parse the result to _json_ and then we assign that result to the state of our component by
by invoking _setMembers_
diff --git a/04-frameworks/01-react/02-base/04-list-users/readme_es.md b/04-frameworks/01-react/02-base/03-list-users/readme_es.md
similarity index 87%
rename from 04-frameworks/01-react/02-base/04-list-users/readme_es.md
rename to 04-frameworks/01-react/02-base/03-list-users/readme_es.md
index 6667083aa..9582f620a 100644
--- a/04-frameworks/01-react/02-base/04-list-users/readme_es.md
+++ b/04-frameworks/01-react/02-base/03-list-users/readme_es.md
@@ -1,8 +1,8 @@
-# 04 List Users
+# 03 List Users
## Resumen
-Este ejemplo toma como punto de partida el ejemplo _03-webpack-react_.
+Este ejemplo toma como punto de partida el ejemplo _02-vite-react_.
Vamos a pedirle a la API de Github la lista de miembros que pertenece a una
organización y vamos a mostrarla por pantalla.
@@ -14,7 +14,7 @@ con TypeScript y como hacer nuestro código más mantenible.
Que vamos a aprender en este ejemplo:
- Cómo crear un componente de visualización sin tener que depender de leer
- de una fuenta remota.
+ de una fuente remota.
- Cómo iterar y mostrar una lista de resultados.
- Cómo hacer una llámada asícnrona para pedir datos a una api remota.
- Cómo meter estos datos en el estado de nuestro componente en React.
@@ -36,7 +36,7 @@ npm install
https://api.github.com/orgs/lemoncode/members
```
-- Vamos a crear un set de datos parecido que mueste dos miembros de una organización.
+- Vamos a crear un set de datos parecido que muestre dos miembros de una organización.
_./src/app.tsx_
@@ -125,7 +125,7 @@ a tener en cuenta:
- Ahora que vemos que funciona vamos a encajar esto en un tabla:
-- Ahora que vemos que funciona vamos a encajar esto en un _grid_, vamos a definir algunos estilos gobales
+- Ahora que vemos que funciona vamos a encajar esto en un _grid_, vamos a definir algunos estilos globales
(revisa [Ejemplo de módulos CSS](https://github.com/Lemoncode/master-frontend-lemoncode/tree/master/03-bundling/01-webpack/12-css-modules), para aprender a configurar el CSS aislado de los componentes).
_./src/styles.css_
@@ -155,6 +155,17 @@ body {
}
```
+Para poder usar los estilos tenemos que importarlos dentro de nuestro proyecto:
+
+\__./src/index.tsx_
+
+```diff
+import React from "react";
+import { createRoot } from "react-dom/client";
+import { App } from "./app";
++ import "./styles.css";
+```
+
- Y vamos a integrarlo en el componente de nuestra aplicación:
_./src/app.tsx_
@@ -183,7 +194,7 @@ export const App = () => {
Así que hemos creado aquí un contenedor CSS Grid añadimos la cabecera y un bucle de todos los elementos de la lista de usuarios.
- Hasta aquí muy bien pero... yo quiero tirar de la API de Github no de datos mockeados, vamos a empezar
- por eliminar los datos mock e inicializar el estado de nuestro componente a un array vacio:
+ por eliminar los datos mock e inicializar el estado de nuestro componente a un array vacío:
```diff
- const membersMock = [
@@ -204,7 +215,7 @@ export const App = () => {
+ const [members, setMembers] = React.useState([]);
```
-- ¿Cómo puedo hacer la llamada al servidor de Github y traerme los datos justo cuando el compomenten se monte en mi HTML?
+- ¿Cómo puedo hacer la llamada al servidor de Github y traerme los datos justo cuando el componente se monte en mi HTML?
Para ello vamos a usar _useEffect_ esto lo veremos más adelante cuando cubramos la parte de hooks
_./src/app.tsx_
@@ -220,7 +231,7 @@ export const App = () => {
```
Aquí ejecutamos un código justo cuando el componente se monta el DOM, los corchetes que nos encontramos al final de useEffect
-son los que indican que sólo se ejecute una sóla vez al montarse el componente, aprenderemos como funciona esto en detalle más adelante.
+son los que indican que sólo se ejecute una sola vez al montarse el componente, aprenderemos como funciona esto en detalle más adelante.
- Ahora nos queda realizar la llamada AJAX dentro de ese _useEffect_
@@ -234,7 +245,9 @@ _./src/app.tsx_
}, []);
```
-¿Qué estamos haciendo aquí? Estamos haciendo una llamada a la API REST de Github, esta api es asíncrona (de ahí que utlicemos
+Más adelante veremos que React 19 ya trae un hook específico para esto.
+
+¿Qué estamos haciendo aquí? Estamos haciendo una llamada a la API REST de Github, esta api es asíncrona (de ahí que utilicemos
promesas), primero parseamos el resultado a _json_ y después asignamos ese resultado al estado de nuestro componente
invocando a _setMembers_
diff --git a/04-frameworks/01-react/02-base/04-list-users/src/app.tsx b/04-frameworks/01-react/02-base/03-list-users/src/app.tsx
similarity index 100%
rename from 04-frameworks/01-react/02-base/04-list-users/src/app.tsx
rename to 04-frameworks/01-react/02-base/03-list-users/src/app.tsx
diff --git a/04-frameworks/01-react/02-base/03-webpack-react/src/index.tsx b/04-frameworks/01-react/02-base/03-list-users/src/index.tsx
similarity index 90%
rename from 04-frameworks/01-react/02-base/03-webpack-react/src/index.tsx
rename to 04-frameworks/01-react/02-base/03-list-users/src/index.tsx
index 7e439b87e..7c541901b 100644
--- a/04-frameworks/01-react/02-base/03-webpack-react/src/index.tsx
+++ b/04-frameworks/01-react/02-base/03-list-users/src/index.tsx
@@ -1,6 +1,7 @@
import React from "react";
import { createRoot } from "react-dom/client";
import { App } from "./app";
+import "./styles.css";
const container = document.getElementById("root");
const root = createRoot(container);
diff --git a/04-frameworks/01-react/02-base/04-list-users/src/styles.css b/04-frameworks/01-react/02-base/03-list-users/src/styles.css
similarity index 100%
rename from 04-frameworks/01-react/02-base/04-list-users/src/styles.css
rename to 04-frameworks/01-react/02-base/03-list-users/src/styles.css
diff --git a/04-frameworks/01-react/02-base/03-list-users/tsconfig.json b/04-frameworks/01-react/02-base/03-list-users/tsconfig.json
new file mode 100644
index 000000000..a057cea1d
--- /dev/null
+++ b/04-frameworks/01-react/02-base/03-list-users/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "compilerOptions": {
+ "esModuleInterop": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "lib": ["ESNext", "DOM"],
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "noEmit": true,
+ "noImplicitAny": false,
+ "noImplicitReturns": true,
+ "resolveJsonModule": true,
+ "skipLibCheck": true,
+ "sourceMap": true,
+ "target": "ESNext",
+ "useDefineForClassFields": true
+ },
+ "include": ["src"]
+}
diff --git a/04-frameworks/01-react/02-base/03-list-users/vite.config.ts b/04-frameworks/01-react/02-base/03-list-users/vite.config.ts
new file mode 100644
index 000000000..a0024d88e
--- /dev/null
+++ b/04-frameworks/01-react/02-base/03-list-users/vite.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from "vite";
+import checker from "vite-plugin-checker";
+import react from "@vitejs/plugin-react";
+
+export default defineConfig({
+ plugins: [checker({ typescript: true }), react()],
+});
diff --git a/04-frameworks/01-react/02-base/03-webpack-react/.babelrc b/04-frameworks/01-react/02-base/03-webpack-react/.babelrc
deleted file mode 100644
index 469d3d55f..000000000
--- a/04-frameworks/01-react/02-base/03-webpack-react/.babelrc
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "presets": [
- "@babel/preset-env",
- "@babel/preset-typescript",
- "@babel/preset-react"
- ]
-}
diff --git a/04-frameworks/01-react/02-base/03-webpack-react/package.json b/04-frameworks/01-react/02-base/03-webpack-react/package.json
deleted file mode 100644
index 50e9c4ccc..000000000
--- a/04-frameworks/01-react/02-base/03-webpack-react/package.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "name": "react-example",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "start": "run-p -l type-check:watch start:dev",
- "type-check": "tsc --noEmit",
- "type-check:watch": "npm run type-check -- --watch",
- "start:dev": "webpack-dev-server --mode development --open",
- "build": "rimraf dist && webpack --mode development"
- },
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "@babel/cli": "^7.17.10",
- "@babel/core": "^7.17.10",
- "@babel/preset-env": "^7.17.10",
- "@babel/preset-react": "^7.17.12",
- "@babel/preset-typescript": "^7.16.7",
- "@types/react": "^18.0.9",
- "@types/react-dom": "^18.0.4",
- "babel-loader": "^8.2.5",
- "css-loader": "^6.7.1",
- "html-loader": "^3.1.0",
- "html-webpack-plugin": "^5.5.0",
- "npm-run-all": "^4.1.5",
- "rimraf": "^3.0.2",
- "style-loader": "^3.3.1",
- "typescript": "^4.6.4",
- "webpack": "^5.72.1",
- "webpack-cli": "^4.9.2",
- "webpack-dev-server": "^4.9.0"
- },
- "dependencies": {
- "react": "^18.1.0",
- "react-dom": "^18.1.0"
- }
-}
diff --git a/04-frameworks/01-react/02-base/03-webpack-react/readme.md b/04-frameworks/01-react/02-base/03-webpack-react/readme.md
deleted file mode 100644
index 9efb29473..000000000
--- a/04-frameworks/01-react/02-base/03-webpack-react/readme.md
+++ /dev/null
@@ -1,114 +0,0 @@
-# 03 Webpack React
-
-## Summary
-
-This example takes the _02-webpack-boiler_ example as a starting point.
-
-We will go step by step adding the necessary configuration so that we integrate
-**React** into our build process.
-
-# Step by Step guide
-
-- First we copy the previous example, and do a _npm install_
-
-```bash
-npm install
-```
-
-- Let's install _react_ and _react-dom_
-
-```bash
-npm install react react-dom --save
-```
-
-- Let's install _react_ and _react-dom_ typings
-
-```bash
-npm install @types/react @types/react-dom --save-dev
-```
-
-This way we have the React library and the bindings to integrate with a web browser.
-
-- In the index.html we are going to put the _div_ that will serve as entry point to instantiate our React application. our React application.
-
-_./src/index.html_
-
-```diff
-
--
;
-};
-```
-
-- It's time to instantiate that main component, to be able to integrate it with the browser we have to make use of _createRoot_.
-
-_./src/index.tsx_
-
-```tsx
-import React from "react";
-import { createRoot } from "react-dom/client";
-import { App } from "./app";
-
-const rootElement = document.getElementById("root");
-const root = createRoot(rootElement);
-
-root.render();
-```
-
-- We are on the right track, but if we try to run this it will fail, since _babel_ does not know how to transform the _jsx_ (remember that this was a sugar, which was actually an XML) into javaScript, in order for babel to be able to understand this we have to install the _preset_ _@babel/preset-react_
-
-First we install it and the configure it.
-
-```bash
-npm install @babel/preset-react --save-dev
-```
-
-_.babelrc_
-
-```diff
-{
- "presets": [
- "@babel/preset-env",
- "@babel/preset-typescript",
-+ "@babel/preset-react"
- ]
-}
-```
-
-> By the way the _rc_ suffix is pretty usual in linux it's stands for "runcom"
-> (CTSS system 1962-63) Script file containing startup instructions for an application program.
-> In other words, "rc" is just something that stuck from back in the sixties, and has been used quite often for configuration files in different sorts of programs since, including Node, Babel and many, many others.
-> More info [on stackoverflow](https://stackoverflow.com/questions/36212256/what-are-rc-files-in-nodejs).
-
-> Another curiosity... what is a _preset_ ... let's start with what is a babel plugin: babel transformations are
-> enabled by applying plugins, there are plenty of plugins and if you have to go adding one by one it can become a nightmare,
-> in order to make this easier, babel has grouped common sets of plugins in _presets_, for instance @babel-preset-react
-> includes the following plugins:
-
-- @babel/plugin-syntax-jsx
-- @babel/plugin-transform-react-jsx
-- @babel/plugin-transform-react-display-name
-
-- Is time to double check the _webpack.config.js_
-
-- We can make sure that we have _ts_ and _tsx_ as valid extensions.
-- Also that in the loader we accept both _ts_ and _tsx_.
-- And in the app we have as entry point _index.tsx_.
-
-* Let's check that things are working as expected:
-
-```bash
-npm start
-```
diff --git a/04-frameworks/01-react/02-base/03-webpack-react/readme_es.md b/04-frameworks/01-react/02-base/03-webpack-react/readme_es.md
deleted file mode 100644
index bb34f2812..000000000
--- a/04-frameworks/01-react/02-base/03-webpack-react/readme_es.md
+++ /dev/null
@@ -1,119 +0,0 @@
-# 03 Webpack React
-
-## Resumen
-
-Este ejemplo toma como punto de partida el ejemplo _02-webpack-boiler_.
-
-Vamos a ir paso a paso añdiendo la configuración necesaria para que integrar
-**React** en nuestro proceso de build.
-
-## Paso a Paso
-
-- Primero copiamos el ejemplo anterior, y hacemos un _npm install_
-
-```bash
-npm install
-```
-
-- Vamos a instalar _react_ y _react-dom_
-
-```bash
-npm install react react-dom --save
-```
-
-- Vamos a instalarnos los typing de _react_ y _react-dom_
-
-```bash
-npm install @types/react @types/react-dom --save-dev
-```
-
-Así tenemos la librería de React y los bindings para que se integre con un navegador web.
-
-- En el index.html vamos a meter el _div_ que nos servirá como punto de entrada para instanciar
- nuestra aplicación React.
-
-_./src/index.html_
-
-```diff
-
--