Skip to content

Commit 78876d4

Browse files
Miguel Angel Chimali CobanoMiguel Angel Chimali Cobano
authored andcommitted
update previous and base
1 parent 83210a9 commit 78876d4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1579
-1060
lines changed
Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
# 01 Previous - Hi React
2+
3+
## Summary
4+
5+
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.
6+
[Here you have the complete example that we are going to develop.](https://codesandbox.io/p/sandbox/react-concepts-rncyq4)
7+
8+
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.
9+
10+
## Step by step
11+
12+
- Rename the file _index.mjs_ to _index.js_ and update the reference in _index.html_.
13+
- Comment out all the content of _index.js_.
14+
- In _index.html_ render a static list of users:
15+
16+
_index.html_
17+
18+
```diff
19+
<!DOCTYPE html>
20+
<html>
21+
<head>
22+
<title>JavaScript Sandbox</title>
23+
<meta charset="UTF-8" />
24+
</head>
25+
26+
<body>
27+
- <div id="app"></div>
28+
+ <div id="app">
29+
+ <h4>Lista de usuarios</h4>
30+
+ <div>1955: Rick Sánchez</div>
31+
+ <div>8765: Beth Harmon</div>
32+
+ <div>7562: Farrokh Bulsara</div>
33+
+ </div>
34+
<script src="./index.js" type="module"></script>
35+
</body>
36+
</html>
37+
```
38+
39+
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.
40+
41+
We leave the HTML empty and move the list into our _index.js_:
42+
43+
_index.html_
44+
45+
```diff
46+
<!DOCTYPE html>
47+
<html>
48+
<head>
49+
<title>JavaScript Sandbox</title>
50+
<meta charset="UTF-8" />
51+
</head>
52+
53+
<body>
54+
+ <div id="app"></div>
55+
- <div id="app">
56+
- <h4>Lista de usuarios</h4>
57+
- <div>1955: Rick Sánchez</div>
58+
- <div>8765: Beth Harmon</div>
59+
- <div>7562: Farrokh Bulsara</div>
60+
- </div>
61+
<script src="./index.js" type="module"></script>
62+
</body>
63+
</html>
64+
```
65+
66+
_index.js_:
67+
68+
```diff
69+
+ import "./styles.css";
70+
71+
+ document.getElementById("app").innerHTML = `
72+
+ <h4>Lista de usuarios</h4>
73+
+ <div>1955: Rick Sánchez</div>
74+
+ <div>8765: Beth Harmon</div>
75+
+ <div>7562: Farrokh Bulsara</div>
76+
+ `;
77+
```
78+
79+
Now the content is generated by JavaScript. We can confirm that it’s the JavaScript file that generates the content.
80+
81+
### Components
82+
83+
Let’s start breaking our list into parts. First, we separate the title:
84+
85+
```diff
86+
import "./styles.css";
87+
88+
+ const Header = () => {
89+
+ return ` <h4>Lista de usuarios</h4>`;
90+
+ };
91+
+
92+
document.getElementById("app").innerHTML = `
93+
- <h4>Lista de usuarios</h4>
94+
+ ${Header()}
95+
<div>1955: Rick Sánchez</div>
96+
<div>8765: Beth Harmon</div>
97+
<div>7562: Farrokh Bulsara</div>
98+
```
99+
100+
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.
101+
102+
Let’s continue splitting or componentizing our application. We’ll create a new component that returns just the list..
103+
104+
```diff
105+
import "./styles.css";
106+
107+
const Header = () => {
108+
return `<h4>Lista de usuarios</h4>`;
109+
};
110+
111+
+ const List = () => {
112+
+ return `
113+
+ <div>
114+
+ <div>1955: Rick Sánchez</div>
115+
+ <div>8765: Beth Harmon</div>
116+
+ <div>7562: Farrokh Bulsara</div>
117+
+ </div>`;
118+
+ };
119+
120+
document.getElementById("app").innerHTML = `
121+
${Header()}
122+
- <div>1955: Rick Sánchez</div>
123+
- <div>8765: Beth Harmon</div>
124+
- <div>7562: Farrokh Bulsara</div>
125+
+ ${List()}
126+
`;
127+
```
128+
129+
### Props
130+
131+
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`:
132+
133+
```diff
134+
import "./styles.css";
135+
136+
const Header = () => {
137+
return `<h4>Lista de usuarios</h4>`;
138+
};
139+
140+
+ const User = (props) => {
141+
+ return `<div>${props.id}: ${props.name}</div>`;
142+
+ };
143+
144+
const List = () => {
145+
return `
146+
<div>
147+
+ ${User({id: 1955, name 'Rick Sánchez'})}
148+
+ ${User({id: 8765, name 'Beth Harmon'})}
149+
+ ${User({id: 7562, name 'Farrokh Bulsara'})}
150+
- <div>1955: Rick Sánchez</div>
151+
- <div>8765: Beth Harmon</div>
152+
- <div>7562: Farrokh Bulsara</div>
153+
</div>`;
154+
};
155+
156+
document.getElementById("app").innerHTML = `
157+
${Header()}
158+
${List()}
159+
`;
160+
```
161+
162+
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.
163+
164+
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_.
165+
166+
```js
167+
export const getUsers = () => [
168+
{ id: 1955, name: "Rick Sánchez" },
169+
{ id: 8765, name: "Beth Harmon" },
170+
{ id: 7562, name: "Farrokh Bulsara" },
171+
];
172+
```
173+
174+
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.
175+
176+
```diff
177+
+ import { getUsers } from './api';
178+
import "./styles.css";
179+
180+
const Header = () => {
181+
return `<h4>Lista de usuarios</h4>`;
182+
};
183+
184+
+ const User = (props) => {
185+
+ return `<div>${props.id}: ${props.name}</div>`;
186+
+ };
187+
188+
const List = () => {
189+
+ const users = getUsers();
190+
return `
191+
<div>
192+
+ ${users.map(user=>User(user)).join('')}
193+
- ${User({id: 1955, name 'Rick Sánchez'})}
194+
- ${User({id: 8765, name 'Beth Harmon'})}
195+
- ${User({id: 7562, name 'Farrokh Bulsara'})}
196+
</div>`;
197+
};
198+
199+
document.getElementById("app").innerHTML = `
200+
${Header()}
201+
${List()}
202+
`;
203+
```
204+
205+
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.
206+
207+
```diff
208+
import { getUsers } from "./api";
209+
import "./styles.css";
210+
211+
const Header = () => {
212+
return `<h4>Lista de usuarios</h4>`;
213+
};
214+
215+
- const User = (props) => {
216+
+ const User = ({ user }) => {
217+
- return `<div>${props.id}: ${props.name}</div>`;
218+
+ return `<div>${user.id}: ${user.name}</div>`;
219+
};
220+
221+
const List = () => {
222+
const users = getUsers();
223+
return `
224+
<div>
225+
- ${users.map((user) => User(user)).join("")}
226+
+ ${users.map((user) => User({ user })).join("")}
227+
</div>`;
228+
};
229+
230+
document.getElementById("app").innerHTML = `
231+
${Header()}
232+
${List()}
233+
`;
234+
```
235+
236+
### Reactivity
237+
238+
Let’s try to render a random number for each element, calculated at the moment the component is invoked.
239+
240+
```diff
241+
const User = ({ user }) => {
242+
+ const randomNumber = Math.random();
243+
- return `<div>${user.id}: ${user.name}</div>`;
244+
+ return `<div>${user.id}: ${user.name} - ${randomNumber}</div>`;
245+
};
246+
```
247+
248+
If we update it with a setTimeout, we see the value changes in the console, but the interface does not update:
249+
250+
```diff
251+
const User = ({ user }) => {
252+
- const randomNumber = Math.random();
253+
+ let randomNumber = Math.random();
254+
+ setTimeout(() => {
255+
+ randomNumber = Math.random();
256+
+ console.log(randomNumber);
257+
+ }, 3000);
258+
return `<div>${user.id}: ${user.name} - ${randomNumber}</div>`;
259+
};
260+
```
261+
262+
Why doesn’t the interface refresh after the three seconds of the setTimeout? Try to think of the answer...
263+
264+
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.
265+
266+
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.
267+
268+
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.
269+
270+
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.
271+
272+
### Events and persistence
273+
274+
```diff
275+
const List = () => {
276+
- const users = getUsers();
277+
+ let users = getUsers();
278+
279+
+ const handleClick = () => {
280+
+ alert("button clicked!");
281+
+ users = [...users, { id: 1234, name: "John Doe" }];
282+
+ };
283+
284+
return `
285+
<div>
286+
${users.map((user) => User({ user })).join("")}
287+
+ <button onclick="javascript:handleClick()">Add user</button>
288+
</div>`;
289+
};
290+
```
291+
292+
The button appears but when clicking it, not even the alert shows up. What’s going on?
293+
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.
294+
295+
This is another problem React solves, since it allows us to persist data and functions between executions of our components.
296+
297+
To leave the example ready for the next exercise, let’s make the following change:
298+
299+
```diff
300+
+ export default function App() {
301+
+ return `
302+
+ ${Header()}
303+
+ ${List()}
304+
+ `;
305+
}
306+
307+
+ document.getElementById("app").innerHTML = App();
308+
- document.getElementById("app").innerHTML = `
309+
- ${Header()}
310+
- ${List()}
311+
- `;
312+
```

0 commit comments

Comments
 (0)