Skip to content

Commit f3be570

Browse files
improving format of blogpost
1 parent 62a6bf0 commit f3be570

File tree

1 file changed

+16
-16
lines changed

1 file changed

+16
-16
lines changed

src/content/blog/saulin18/Est-s-usando-mal-React.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ canonicalUrl: ""
1111
A lo largo de mis años en el desarrollo web con React he visto muchas veces que tienes que volver atrás a modificar componentes (o incluso rehacerlos desde 0) porque desde el inicio no se diseñó bien el componente, esto está **mal**.
1212

1313
Imagina que necesitas un componente button:
14-
14+
```
1515
// Button.tsx
1616
import React from 'react';
1717
@@ -31,7 +31,7 @@ Imagina que necesitas un componente button:
3131
export default Button;
3232
3333
<Button onClick={() => alert('Botón clickeado')} text="Click aquí" />
34-
34+
```
3535
Este componente en primera instancia puede parecer que cumple para lo que fue asignado, pero a medida que crece el proyecto hay una gran posibilidad de que tengas que hacerle muchos cambios por no hacerlo más abierto a la modificación.
3636

3737
**Problemas iniciales:**
@@ -43,7 +43,7 @@ Este componente en primera instancia puede parecer que cumple para lo que fue as
4343
**¿Cómo mejorar este componente?**
4444

4545
Sencillamente tipando correctamente el evento de onClick y usando la prop children en lugar de pasarle el text como un string por props. Así no cierras el contenido que le puedes pasar al button haciéndolo más flexible.
46-
46+
```
4747
// Button.tsx
4848
import React, { MouseEvent, ReactNode } from 'react';
4949
@@ -66,15 +66,15 @@ Sencillamente tipando correctamente el evento de onClick y usando la prop childr
6666
// <Button onClick={() => alert('¡Hola!')}>Click aquí</Button>
6767
// <Button onClick={() => alert('Icono!')}><img src="icon.png" alt="icono" /></Button>
6868
// <Button onClick={() => alert('Div!')}><div>Contenido</div></Button>
69-
69+
```
7070
## ComponentPropsWithRef, ComponentPropsWithoutRef, ComponentPropsWithChildren, la clave para hacer componentes reutilizables.
7171

7272
Incluso con los cambios anteriores, ese componente sigue sin ser del todo reutilizable, aún mantiene implementaciones en su estructura. Si quisieras añadir una nueva funcionalidad al botón, como cambiar su type (a submit, reset, etc.) o añadirle un handler para un evento, tendrías que ir al componente Button y añadir esas props una por una.
7373

7474
Aquí es donde React nos da una joya: ComponentPropsWithRef (o ComponentProps si no necesitas pasar referencias). Este tipo te permite heredar todas las propiedades nativas de un elemento HTML. Así tu componente de automáticamente aceptará type, onBlur, className, id, style, y todo lo que un componente HTML nativo pueda tener.
7575

7676
El truco es hacer **spread** de esas props al elemento HTML del que se extiende. Esto debería hacerse en todos tus componentes que envuelvan elementos HTML primitivos.
77-
77+
```
7878
// Button.tsx
7979
import React, { MouseEvent, ReactNode, ComponentPropsWithRef } from 'react';
8080
@@ -103,9 +103,9 @@ Incluso con los cambios anteriores, ese componente sigue sin ser del todo reutil
103103
// <Button type="submit" onClick={(e) => e.preventDefault()}>Enviar Formulario</Button>
104104
// <Button onBlur={() => console.log('Salió del botón')} className="bg-blue-500 text-white p-2">Foco</Button>
105105
// <Button aria-label="Cerrar ventana">X</Button>
106-
106+
```
107107
Ahora nuestro componente recibe autocompletado, es cómodo para extender y está abierto a la extensión. Este mismo truco del ComponentPropsWithRef, ComponentPropsWithoutRef, ComponentPropsWithChildren, etc, lo pueden usar en cada elemento que envuelva un elemento HTML primitivo.
108-
108+
```
109109
// Ejemplo con Input
110110
import React, { ComponentPropsWithRef } from 'react';
111111
@@ -122,7 +122,7 @@ Incluso con los cambios anteriores, ese componente sigue sin ser del todo reutil
122122
// Uso:
123123
// <Input type="text" placeholder="Tu nombre" onChange={(e) => console.log(e.target.value)} />
124124
// <Input type="email" required />
125-
125+
```
126126
**Lógica Personalizada y Cómo Evitar Sobreescrituras**
127127

128128
A veces querrás añadir tu propia lógica a las props nativas. Por ejemplo, podrías querer registrar un evento "X" cada vez que se hace clic en un botón además de la función onClick que el usuario pueda pasar.
@@ -132,7 +132,7 @@ El orden de esparcir las props importa. Si tienes una prop personalizada y una p
132132
**Esparce las props antes de tus propiedades personalizadas.**
133133

134134
Ejemplo:
135-
135+
```
136136
// Button.tsx
137137
import React, { MouseEvent, ReactNode, ComponentPropsWithRef } from 'react';
138138
@@ -166,9 +166,9 @@ Ejemplo:
166166
// Uso:
167167
// <Button onClick={() => alert('El usuario hizo click!')}>Mi Botón</Button>
168168
// Aquí, la función 'handleInternalClick' se ejecutará primero, luego 'alert'
169-
169+
```
170170
Ejemplo con el className:
171-
171+
```
172172
// Button.tsx
173173
import React, { ReactNode, ComponentPropsWithRef } from 'react';
174174
@@ -196,7 +196,7 @@ Ejemplo con el className:
196196
// Uso:
197197
// <Button className="w-full mt-4">Guardar</Button>
198198
// El botón tendrá las clases base Y "w-full mt-4"
199-
199+
```
200200
**Props por defecto y el uso de props opcionales.**
201201

202202
Muchos elementos HTML tienen comportamientos por defecto. Esto puede causar resultados inesperados.
@@ -208,7 +208,7 @@ Si una prop es necesaria para una nueva característica, hay dos maneras de mane
208208
- Definir un valor por defecto: Si no se pasa la prop, tendrá un valor predeterminado.
209209

210210
- Manejar undefined: Si la prop no se pasa, la lógica de tu componente debe ser capaz de funcionar sin ella.
211-
211+
```
212212
import React from 'react';
213213
214214
interface ButtonProps extends React.ComponentPropsWithRef<'button'> {
@@ -245,11 +245,11 @@ Si una prop es necesaria para una nueva característica, hay dos maneras de mane
245245
</button>
246246
);
247247
};
248-
248+
```
249249
**Composition**
250250

251251
Todos los componentes que hemos visto han sido simples, cascarones, base, pero no siempre tenemos componentes así. Muchas veces tenemos componentes que componen por ejemplo un Button, un Input y en el mismo componente manejamos el estado de error (la clave es identificar los elementos relacionados de la UI). Aquí es donde entra la Composition. Podemos hacer un componente que haga spread y extienda de varios componentes HTML para así hacerlo aún más reutilizable.
252-
252+
```
253253
// InputField.tsx
254254
import React, { ComponentPropsWithRef, ReactNode } from 'react';
255255
@@ -315,7 +315,7 @@ Todos los componentes que hemos visto han sido simples, cascarones, base, pero n
315315
};
316316
317317
export default InputField;
318-
318+
```
319319
Este enfoque, donde construyes componentes robustos y flexibles que se basan en los elementos HTML nativos y se pueden extender fácilmente, es una forma excelente de trabajar en React. Verás que muchas librerías de componentes modernas, como Shadcn, adoptan principios muy similares.
320320

321321
PD: El uso de Typescript no se aborda en este artículo por no ser una introducción a React, sino más bien a buenas prácticas. Si no estás usando Typescript **por favor**, empieza a hacerlo.

0 commit comments

Comments
 (0)