Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c532d20
boiler plate
Aug 4, 2025
339eaba
refactor: update react boiler plate to vite
Aug 25, 2025
c88233a
translate vite boiler to spanish
Aug 25, 2025
5bb1c2c
refactor list users - react 19
Aug 28, 2025
86964d1
update readme
Aug 28, 2025
cb6f6e8
refactor react 19 - vite
Aug 28, 2025
32108d9
update folder name - cleaning folder
Aug 28, 2025
cd8d97b
previous code sandbox readme - work in progress
Aug 28, 2025
e3e918d
refactor react concepts
Aug 28, 2025
4c00098
react basic readme
Aug 29, 2025
a4ed3f2
update with codesandbox links
Aug 29, 2025
ff6b536
refactor react 19 - vite
Aug 29, 2025
cca77ae
refactor react 19 - vite - useState hook
Aug 29, 2025
1ea7738
refactor react 19 - vite - useState hook object
Sep 1, 2025
d73bb9d
refactor react 19 - vite - useEffect hook
Sep 1, 2025
a972bc7
refactor react 19 - vite - useEffect hook
Sep 1, 2025
c0b5469
add missing react and react-dom types
Sep 1, 2025
09c9ba3
refactor react 19 - vite - ajax fields exercise
Sep 1, 2025
3ade6fc
new example of use hook - react 19
Sep 1, 2025
4802b16
example of use hook - review
Sep 1, 2025
a8f047b
folder rename
Sep 1, 2025
a5dc3f2
refactor react 19 - vite - pure and memos
Sep 1, 2025
5f5ec07
refactor react 19 - vite - README - contexts
Sep 1, 2025
6f7b30f
refactor react 19 - vite
Sep 1, 2025
316a918
correction
Sep 1, 2025
8e90d02
corrections
Sep 1, 2025
2f840dc
refactor react 19 - vite - basic app
Sep 1, 2025
711efc1
01-previous and 02-base - review
Sep 2, 2025
182ea89
review react hooks - use-state
Sep 2, 2025
9af9f5a
react hooks 1
Sep 2, 2025
24439ed
grammar corrections
Sep 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
312 changes: 312 additions & 0 deletions 04-frameworks/01-react/01-previous/01-concepts/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,312 @@
# 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
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Sandbox</title>
<meta charset="UTF-8" />
</head>

<body>
- <div id="app"></div>
+ <div id="app">
+ <h4>Lista de usuarios</h4>
+ <div>1955: Rick Sánchez</div>
+ <div>8765: Beth Harmon</div>
+ <div>7562: Farrokh Bulsara</div>
+ </div>
<script src="./index.js" type="module"></script>
</body>
</html>
```

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
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Sandbox</title>
<meta charset="UTF-8" />
</head>

<body>
+ <div id="app"></div>
- <div id="app">
- <h4>Lista de usuarios</h4>
- <div>1955: Rick Sánchez</div>
- <div>8765: Beth Harmon</div>
- <div>7562: Farrokh Bulsara</div>
- </div>
<script src="./index.js" type="module"></script>
</body>
</html>
```

_index.js_:

```diff
+ import "./styles.css";

+ document.getElementById("app").innerHTML = `
+ <h4>Lista de usuarios</h4>
+ <div>1955: Rick Sánchez</div>
+ <div>8765: Beth Harmon</div>
+ <div>7562: Farrokh Bulsara</div>
+ `;
```

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. First, we separate the title:

```diff
import "./styles.css";

+ const Header = () => {
+ return ` <h4>Lista de usuarios</h4>`;
+ };
+
document.getElementById("app").innerHTML = `
- <h4>Lista de usuarios</h4>
+ ${Header()}
<div>1955: Rick Sánchez</div>
<div>8765: Beth Harmon</div>
<div>7562: Farrokh Bulsara</div>
```

This function we just created, in React, is a component. That is, **in React, components are functions.** For now, this component returns a piece of our application, in this case the title, which renders something in the DOM.

Let’s continue splitting or componentizing our application. We’ll create a new component that returns just the list..

```diff
import "./styles.css";

const Header = () => {
return `<h4>Lista de usuarios</h4>`;
};

+ const List = () => {
+ return `
+ <div>
+ <div>1955: Rick Sánchez</div>
+ <div>8765: Beth Harmon</div>
+ <div>7562: Farrokh Bulsara</div>
+ </div>`;
+ };

document.getElementById("app").innerHTML = `
${Header()}
- <div>1955: Rick Sánchez</div>
- <div>8765: Beth Harmon</div>
- <div>7562: Farrokh Bulsara</div>
+ ${List()}
`;
```

### 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 `<h4>Lista de usuarios</h4>`;
};

+ const User = (props) => {
+ return `<div>${props.id}: ${props.name}</div>`;
+ };

const List = () => {
return `
<div>
+ ${User({id: 1955, name 'Rick Sánchez'})}
+ ${User({id: 8765, name 'Beth Harmon'})}
+ ${User({id: 7562, name 'Farrokh Bulsara'})}
- <div>1955: Rick Sánchez</div>
- <div>8765: Beth Harmon</div>
- <div>7562: Farrokh Bulsara</div>
</div>`;
};

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 `<h4>Lista de usuarios</h4>`;
};

+ const User = (props) => {
+ return `<div>${props.id}: ${props.name}</div>`;
+ };

const List = () => {
+ const users = getUsers();
return `
<div>
+ ${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'})}
</div>`;
};

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 `<h4>Lista de usuarios</h4>`;
};

- const User = (props) => {
+ const User = ({ user }) => {
- return `<div>${props.id}: ${props.name}</div>`;
+ return `<div>${user.id}: ${user.name}</div>`;
};

const List = () => {
const users = getUsers();
return `
<div>
- ${users.map((user) => User(user)).join("")}
+ ${users.map((user) => User({ user })).join("")}
</div>`;
};

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 `<div>${user.id}: ${user.name}</div>`;
+ return `<div>${user.id}: ${user.name} - ${randomNumber}</div>`;
};
```

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 `<div>${user.id}: ${user.name} - ${randomNumber}</div>`;
};
```

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 `
<div>
${users.map((user) => User({ user })).join("")}
+ <button onclick="javascript:handleClick()">Add user</button>
</div>`;
};
```

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()}
- `;
```
Loading