diff --git a/src/content/lesson/database-normalization.es.md b/src/content/lesson/database-normalization.es.md
new file mode 100644
index 000000000..31201a6c8
--- /dev/null
+++ b/src/content/lesson/database-normalization.es.md
@@ -0,0 +1,151 @@
+## Conceptos básicos
+
+Cuando hablamos de bases de datos relacionales La principal ventaja que se nos viene a la mente es la integridad de los datos estas bases de datos permiten distribuir la información en Tablas distintas para agrupar información Según sea pertinente y crear relaciones entre las tablas para asociar la información. sin embargo para mantener la integridad es necesario cumplir ciertos estándares a la hora de diseñar nuestras tablas Necesitamos que la estructura sea pertinente a los datos que queremos almacenar y que garantice la integridad de la información así como su consistencia y evite Tener información redundante innecesaria.
+
+Para ello existe la normalización de base de datos. se trata de cinco formas normales que de cumplirlas tu base de datos garantizará la integridad de la información y la optimización a la hora de hacer consultas. las formas cuatro y cinco generalmente se contemplan para escenarios más avanzados y de mayor complejidad, para la mayoría de los casos bastará con cumplir las tres primeras formas normales que cubriremos a continuación en este artículo.
+
+Antes de hablar de las formas normales debemos manejar algunos conceptos fundamentales.
+
+El primer concepto es entidad, se trata de una abstracción de un objeto de la realidad o de un proceso de la organización cuyos datos deben ser almacenados en la base de datos de manera agrupada y correlacionada.
+
+El segundo es llave primaria, se trata de un atributo o columna que sirve para identificar de manera inequívoca a una entidad dentro de una tabla.
+
+
+## Primera forma Normal - 1NF
+
+Para que una tabla cumpla con la primera forma normal debe cumplir los siguientes parámetros:
+
+
+
+* Cada celda debe tener un único valor
+* Debe haber una llave primaria para identificar cada entidad
+* No debe haber filas o columnas duplicadas
+
+Si por ejemplo tenemos una tabla de pedidos de productos de la siguiente forma:
+
+
+
+
+
Pedido
+
+
Detalle
+
+
Cliente
+
+
+
+
1
+
+
2 Zapatos
+
+
Pedro
+
+
+
+
1
+
+
3 Pantalones
+
+
Pedro
+
+
+
+
2
+
+
1 Bolso
+
+
María
+
+
+
+
3
+
+
1 Camisa
+
+
Ana
+
+
+
+
+
+Podemos notar que la columna detalle contiene dos datos importantes para el pedido la cantidad y la información del producto. de la misma forma podemos notar como si bien Podemos identificar el pedido con el ID no ocurre lo mismo en el caso de los productos y del cliente puesto que solo tenemos un nombre que No necesariamente es único para cada uno y puede ser repetido.
+
+
+
+
+
Pedido
+
+
IdProducto
+
+
NombreProducto
+
+
Cantidad
+
+
IdCliente
+
+
Cliente
+
+
+
+
1
+
+
1z
+
+
Zapatos
+
+
2
+
+
1
+
+
Pedro
+
+
+
+
1
+
+
3P
+
+
Pantalones
+
+
3
+
+
1
+
+
Pedro
+
+
+
+
2
+
+
2B
+
+
Bolso
+
+
1
+
+
2
+
+
María
+
+
+
+
3
+
+
2Z
+
+
Zapatos
+
+
1
+
+
3
+
+
Ana
+
+
+
+
+
+Ahora podemos ver cómo no solo el pedido se puede identificar con su ID sino que también Contamos con ideas para el producto y el cliente de manera que cada una de estas entidades pueda ser identificada.
+
+
+## Segunda forma normal - 2NF.
diff --git a/src/content/lesson/optimize-react-components-usereducer.es.md b/src/content/lesson/optimize-react-components-usereducer.es.md
index c3b3c3512..429aed2fe 100644
--- a/src/content/lesson/optimize-react-components-usereducer.es.md
+++ b/src/content/lesson/optimize-react-components-usereducer.es.md
@@ -1,6 +1,6 @@
---
-title: "Qué es y como usar el hook useReducer en React.js"
-subtitle: "Aprende a usar el hook useReducer en React.js y cómo funciona, comparalo con otras alternativas como redux, flux, entre otras."
+title: "¿Qué es y cómo usar el hook useReducer en React.js"
+subtitle: "Aprende a usar el hook useReducer en React.js y cómo funciona, compáralo con otras alternativas como redux, flux, entre otras."
cover: "https://www.desktopbackground.org/p/2013/09/13/637935_nasa-wallpapers_1600x1200_h.jpg"
textColor: "white"
date: "2024-01-16T16:45:31-04:00"
@@ -12,25 +12,17 @@ status: "draft"
## Que es el useReducer
Los hooks empezaron a existir en react desde la versión 16.8.
-Desde entonces, toda la arquitectura de react se ha transformado en una serie de "Hooks" que permiten implementar la mayoria de los patrones de programacion mas importantes.
-El useReducer es una propuesta de React para separar la logica de la vista en tus componentes. Hay otras soluciones como Redux, Flux, Global Context, etc. Sin embargo, el useReducer es sencillo de usar y mantiene un alcance local sobre los datos, es decir, a pesar de reusar las funciones y codigo de los componentes, no se compartiran los datos entre sí.
+Desde entonces, toda la arquitectura de react se ha transformado en una serie de "Hooks" que permiten implementar la mayoría de los patrones de programación mas importantes.
-## Ejemplo de useReducer
-
-Este es el ejemplo más sencillo de useReducer:
+El useReducer es una nueva propuesta de React para separar la logica de la vista en tus componentes. Hay otras soluciones como Redux, Flux, Global Context, etc. Sin embargo, el useReducer se ha vuelto popular por ser sencillo de usar y mantener un alcance local sobre los datos, es decir, a pesar de reutilizar las funciones y código de los componentes, no se compartirán los datos entre sí.
-```react
- const intitialCounter = () => ({counter: 0});
- const [state, dispatch] = useReducer(counterReducer, intitialCounter());
-```
+> Separar los datos de los componentes ayudar a prevenir errores comunes y reutilizar la información y la lógica en la aplicación.
-El hook `useReducer` recibe como primer parámetro una función que define el `reducer`, y va a retornar un arreglo de dos valores que representan al nuevo estado (`state`) y el dispatcher: El objeto que permite ejecutar las acciones/funciones de la lógica del reducer (`actions`). Como segundo parámetro se debe pasar una función que retorne un objeto con los valores iniciales del estado.
-
-> El segundo valor del arreglo que deveulve el useReducer se llama "dispacher" y no "actions" porque es necesario tener un "despachador" de acciones como intermediario para evitar conflictos en los datos.
+## Ejemplo de useReducer
-A su vez la función reducer (en este ejemplo se llama `counterReducer`) se define con 2 parámetros: El `state` que contiene los datos del reducer, y un objeto `"actions"` que se usa para identificar las acciones que podemos ejecutar para manipular el state.
+El primer paso es declarar una función reducer (en este ejemplo se llama `counterReducer`) se define con 2 parámetros: El `state` que contiene los datos del reducer, y un objeto `actions` que se usa para identificar las acciones que podemos ejecutar para manipular el state.
-```react
+```javascript
function counterReducer(state , action = {}) {
// Aquí el reducer recibe el estado actual
// luego ejecuta las acciones
@@ -38,21 +30,31 @@ function counterReducer(state , action = {}) {
}
```
-Esta función reducer se va a ejecutar en cada llamado de acción y deberá retornar una nueva versión del estado que reemplaza por completo la anterior al terminar su ejecución, por lo que hay que ser cuidadoso y sólo alterar lo que necesitamos y retornar siempre los demás valores del estado utilizando la desestructuracion (js destructuring) 🤓.
+Esta función reducer se encarga de mutar (o "modificar") el estado de tu componente en función de los tipos de acciones predefinidas, y deberá retornar una nueva versión del estado que reemplaza por completo la anterior al terminar su ejecución, por lo que hay que ser cuidadoso y sólo alterar lo que necesitamos y retornar siempre los demás valores del estado utilizando la desestructuracion (js destructuring) 🤓.
-👍**SI**
```javascript
-return { ...state, counter: state.counter + 1 }
+function counterReducer(state , action = {}) {
+ // Hagas lo que hagas, siempre retorna un nuevo estado
+
+ //👍**SI**
+ return { ...state, counter: state.counter + 1 }
+
+ //🚫**NO**
+ //return { counter: state.counter + 1 }
+}
```
-🚫**NO**
+Esta función se utiliza como primer parámetro del hook `useReducer`. Como segundo parámetro se debe pasar una función que retorne un objeto con los valores iniciales del estado.
+
+El llamado al hook retorna un arreglo de dos valores que representan al nuevo estado (`state`) y el dispatcher: El objeto que llama la ejecución de las acciones de la lógica del reducer (`actions`).
```javascript
-return { counter: state.counter + 1 }
+ const intitialCounter = () => ({counter: 0});
+ const [state, dispatch] = useReducer(counterReducer, intitialCounter());
```
-Dentro del reducer, el objeto `actions` contiene una propiedad `type` que nos indica que acción ha sido invocada, y podremos escribir la lógica basado en ello.
+Dentro del reducer, el objeto `actions` contiene una propiedad `type` que nos indica qué acción ha sido invocada, y podremos escribir la lógica mutar el estado por completo.
```javascript
export default function counterReducer(state, action = {}) {
@@ -69,21 +71,23 @@ export default function counterReducer(state, action = {}) {
return { ...state, counter: 0 };
default:
// En caso no tener ningún tipo se retorna el estado sin alterar
- return state;
+ throw Error("No se encuentra la acción especificada")
}
}
```
+Ademas de las acciones especificadas, se coloca un caso `default` que se ejecuta cuando el tipo de acción no esta definido, para lo cual se arroja un error que interrumpe la aplicación. Esto puede parecer un poco extremo, pero es mejor tener un error visible y depurarlo, que tener una aplicación sin errores(🐞bugs) pero que no funciona como debería.
+
Ya con esto podemos tener tanto las funciones `counterReducer` e `intitialCounter` exportadas en un archivo, para ser utilizadas por cualquier otro componente 👌.
## Porque usar useReducer
-Estamos acostumbrados a percibir los componentes como la unidad que agrupa la vista y la lógica para su funcionamiento. Por ejemplo: En el siguiente código hay un componente `Counter` que tiene el HTML para definir como debería verse un contador de números y tambien existe la logica de como deberia sumar una unidad cada vez que se presione el botón "+1"
+Estamos acostumbrados a percibir los componentes como la unidad que agrupa la vista y la lógica para su funcionamiento. Por ejemplo: En el siguiente código hay un componente `Counter` que tiene el HTML para definir como debería verse un contador de números y también existe la lógica de como sumar una unidad cada vez que se presione el botón "+1"
```jsx
export default function Counter() {
- // Logica ⬇️
+ // Lógica ⬇️
const [counter, setCounter] = useState(0);
const increment = () => setCounter(counter + 1);
@@ -102,7 +106,7 @@ export default function Counter() {
Pero ¿Qué pasa si necesitamos reutilizar sólo la lógica en otros componentes? Podríamos [hablar de estados centralizados](https://4geeks.com/es/lesson/context-api-es), pero ¿Qué pasa si sólo quiero reutilizar la lógica y que cada componente tenga un estado propio? Una solución poco práctica seria copiar y pegar, o exportar las funciones desde un archivo aparte y buscar alguna manera de hacerlas trabajar con el estado de cada componente 😰. Eso no suena conveniente...
-La solución a este problema es `useReducer`, que como dice su nombre, su función es **reducir** un estado y su lógica a una unidad reutilizable, permitiendo que esta se pueda exportar desde un archivo a los componentes que lo necesiten 💪. Este reducer va a cohexistir con el resto de la sintaxis típica de un componente React, puedes [aprender más aquí](https://4geeks.com/es/lesson/making-react-components-es).
+Una solución a este problema es `useReducer`, que como dice su nombre, su función es **reducir** un estado y su lógica a una unidad reutilizable, permitiendo que esta se pueda exportar desde un archivo a los componentes que lo necesiten 💪. Este reducer va a coexistir con el resto de la sintaxis típica de un componente React, puedes [aprender más aquí](https://4geeks.com/es/lesson/making-react-components-es).
## Migrando de useState a useReducer
@@ -110,9 +114,9 @@ En este ejemplo tenemos un contador que no solamente suma de 1 en 1, sino tambi
![react counter using state](https://breathecode.herokuapp.com/v1/media/file/state-counter-png?width=200)
-Para realizar todas estas acciones se necesitan funciones para cada una de ellas, ademas del estado en si. Para eso usaremos el clasico hook `useState`, [aprende mas aquí](https://4geeks.com/es/lesson/react-hooks-explained-es).
+Para realizar todas estas acciones se necesitan funciones para cada una de ellas, ademas del estado en si. Para eso usaremos el clásico hook `useState`, [aprende mas aquí](https://4geeks.com/es/lesson/react-hooks-explained-es).
-```react
+```jsx
export default function CounterUsingState() {
const [counter, setCounter] = useState(0);
const increment = () => setCounter(counter + 1);
@@ -139,7 +143,7 @@ export default function CounterUsingState() {
Esto funciona perfecto, pero para hacer la lógica reutilizable y moverlo a otro archivo, lo convertiremos en un reducer:
-```react
+```javascript
// counterReducer.js
export const intitialCounter = () => ({
counter: 0
@@ -165,7 +169,7 @@ export default function counterReducer(state, action = {}) {
Ahora desde el componente importamos y hacemos uso del reducer:
-```react
+```jsx
import React, { useReducer } from "react";
import counterReducer, { intitialCounter } from "./counterReducer";
@@ -206,6 +210,6 @@ Para que esto funcione fue necesario usar el state del reducer y reemplazar las
## Todo listo
-Ya hemos visto las ventajas de useReducer y sabemos como extraer la lógica de nuestro estado a un reducer ubicado en un archivo externo que pueden reutilizar los demás componentes. Esto no significa que tengas que desechar `useState` por completo y solo usar `useReducer`, como todo en programación se trata de usar la herramienta adecuada para el trabajo adecuado. Puedes aprender más de React y las herramientas que tiene [en esta categoria](https://4geeks.com/es/technology/reactjs)
+Ya hemos visto las ventajas de useReducer y sabemos como extraer la lógica de nuestro estado a un reducer ubicado en un archivo externo que pueden reutilizar los demás componentes. Esto no significa que tengas que desechar `useState` por completo y solo usar `useReducer`, como todo en programación se trata de usar la herramienta adecuada para el trabajo adecuado. Puedes aprender más de React y las herramientas que tiene [en esta categoría](https://4geeks.com/es/technology/reactjs)
Los reducer son ideales cuando tenemos muchas funciones asociadas al estado, y nos convenga agrupar lógica y datos. Esto puede darse en un escenario de gran complejidad o cuando se necesite reutilizar funciones y estados en varios componentes, ahi tendrás la poderosa herramienta de **useReducer** en tu arsenal.
diff --git a/src/content/lesson/optimize-react-components-usereducer.md b/src/content/lesson/optimize-react-components-usereducer.md
index 3b014106c..2421513f4 100644
--- a/src/content/lesson/optimize-react-components-usereducer.md
+++ b/src/content/lesson/optimize-react-components-usereducer.md
@@ -12,41 +12,45 @@ status: "draft"
## What is the useReducer hook?
-The hooks were launched on version 16.8 of React. Since then all the architecture of react has transformed into a series of hooks that allow the implementation of most of the most important coding design patterns.
+The hooks were launched on version 16.8 of React. Since then all the architecture of react has transformed into a series of hooks that allow the implementation of most of the most important coding design patterns.
+
useReducer is a proposal from React to separate the logic from the view of your components. There are other solutions like Redux, Flux, Global Context, etc; however, useReducer is easy to use and keeps the data in a local scope, which means that even when the components are reusing the functions, they don't share data.
## Example of a useReducer
-The `useReducer` hook receives as the first parameter a function that defines the `reducer` and will return an array of two values that represents the state of the reducer (`state`) and the object that allows dispatching the actions that perform the logic of the reducer (`actions`). As a second parameter, it receives a function that returns an object with the initial values of the state.
-
-```javascript
- const intitialCounter = () => ({counter: 0});
- const [state, dispatch] = useReducer(counterReducer, intitialCounter());
-```
-
-At the same time, the reducer function itself is defined with 2 parameters: The `state` that has all the data of the reducer, and an object that is used to identify the actions that must be performed inside it (which we'll call `actions`).
+The first step is to declare a reducer function wich is defined with 2 parameters: The `state` that has all the data of the reducer, and an `actions` object that is used to identify the actions can be performed to manipulate the state.
```javascript
function counterReducer(state , action = {}) {
// Here the reducer receives the state and execute the actions
+ // at last, it returns a new state.
}
```
-This reducer function will be executed on every action call and it must return the new version of the state which replaces entirely the previous one at the end of the execution, which is why you must be careful to only write what you need and keep all the other values intact by using destructuring 🤓.
+This reducer function is in charge of mutate (modify) the state of your component according to the predefined action types, and it must return the new version of the state which replaces entirely the previous one at the end of the execution, which is why you must be careful to only write what you need and keep all the other values intact by using destructuring 🤓.
-👍**YES**
```javascript
-return { ...state, counter: state.counter + 1 }
+function counterReducer(state , action = {}) {
+ // Whatever you do, always return a new state
+ //👍**YES**
+ return { ...state, counter: state.counter + 1 }
+
+ //🚫**NO**
+ //return { counter: state.counter + 1 }
+}
```
-🚫**NO**
+This function is meant to be used as the first parameter of the `useReducer` hoook. As a second parameter, it receives a function that returns an object with the initial values of the state.
+
+The hook call returns an array of two values that represents the state (`state`) and the dispatcher: The object that call the executions of actions that perform the logic of the reducer (`actions`).
```javascript
-return { counter: state.counter + 1 }
+ const intitialCounter = () => ({counter: 0});
+ const [state, dispatch] = useReducer(counterReducer, intitialCounter());
```
-Inside the reducer, the object `actions` contain the property `type` that indicates to us which action has been invoked, and we can write the logic based on it.
+Inside the reducer, the object `actions` contain the property `type` that indicates which action has been invoked, and we can write the logic to mutate the state entirely.
```javascript
export default function counterReducer(state, action = {}) {
@@ -72,6 +76,28 @@ With this, we can have the functions `counterReducer` and `intitialCounter` expo
## Why use useReducer?
+We are used to perceive the components as the unit that groups the view and the logic for its operation. For example: In the following code there is a `Counter` component that has the HTML to define how a counter of numbers should look like and there is also the logic of how it adds a unit each time the "+1" button is pressed.
+
+```jsx
+export default function Counter() {
+
+ // Logic ⬇️
+ const [counter, setCounter] = useState(0);
+ const increment = () => setCounter(counter + 1);
+
+ // View ⬇️
+ return (
+
+
State counter
+
{counter}
+
+
+
+
+ );
+}
+```
+
What if we need to reuse only the logic in other components? We could consider [centralized states](https://4geeks.com/lesson/context-api), but what if I want to reuse only the logic while leaving every component with its own state? The janky solution would be copying the functions to another file, exporting them from there, and figuring out a way to make them work with every single state component 😰. It doesn't sound convenient...
One solution for this issue is `useReducer`, which as its name suggests **reduces** the state and the logic to a single reusable unit, allowing it to be exported from a file to every component that needs it 💪. This reducer will coexist with the rest of the ordinary component syntax, you can [learn more here](https://4geeks.com/lesson/making-react-components).
diff --git a/src/content/lesson/react-design-patterns.es.md b/src/content/lesson/react-design-patterns.es.md
index 4cdeb906b..cac45fd7d 100644
--- a/src/content/lesson/react-design-patterns.es.md
+++ b/src/content/lesson/react-design-patterns.es.md
@@ -1 +1,239 @@
-# https://codesandbox.io/p/sandbox/higher-order-component-card-vv2grj?file=%2Fsrc%2FPlanetCard.js
+## ¿Que son patrones de diseño?
+
+La programación se trata de escribir instrucciones para ser interpretadas por una maquina, lo que nos lleva en muchos casos a que existan varias formas de solucionar un mismo problema. Aun asi hay asuntos comunes que se deben considerar a la hora de hacer crecer un sistema o lograr que tenga un buen desempeño si tiene una gran concurrencia, ahi los patrones de diseño nos ayudan a dar solución a estos escenarios.
+
+> Los patrones de diseño son estrategias para solucionar problemas comunes en la programación. Algunos solucionan problemas de reutilización de código, otros problemas de escalabilidad o eficiencia. No se trata de librerías o frameworks específicos, son mas bien formas de utilizar las herramientas que te ofrece una determinada tecnología, para evitar problemas que ya son bien conocidos y cuyas soluciones ya han sido probadas.
+
+Los planteamientos de los patrones de diseño se hacen de forma genérica, de manera que puedan ser implementados en contextos específicos con sus propias particularidades. En éste articulo vamos a ver algunos patrones utilizados en React y que sirven para hacer nuestra aplicación mas escalable y eficiente.
+
+## Patrón proveedor (Provider)
+
+Este patrón se popularizo en la comunidad de React desde que se introdujo la api de contexto (Context API), se trata de básicamente de crear un componente que **provee** de un estado a todos los componentes en su interior. Tratándose de aplicaciones que se forman en base a componentes, se pueden crear varias capas de proveedores (cada una dentro de otra) que provean de varios contextos a tu aplicación.
+
+![Las apps de react son como cebollas](https://breathecode.herokuapp.com/v1/media/file/apps-de-react-son-como-cebollas "Las apps de react son como cebollas")
+
+Algunas librerías implementan este patrón por defecto, como por ejemplo React Router que envuelve toda la aplicación en un componente `` y luego te permite crear layouts con rutas dinámicas con el componente ``, creando asi varias capas de proveedores. Si quieres saber más de como usar React Router puedes visitar [éste artículo](https://4geeks.com/es/lesson/routing-our-views-with-react-router-es).
+[this article](https://4geeks.com/lesson/routing-our-views-with-react-router).
+
+Claro que también puedes crear tus propios contextos con lo que necesites, por ejemplo puedes crear un contexto que sirva para cambiar el diseño de tu aplicación de un modo claro a un modo oscuro, veamos como hacerlo:
+
+``` jsx
+// ThemeProvider.jsx
+import React, { createContext, useContext, useState } from "react";
+
+// Crearemos nuestro contexto y creamos la instancia que se va a exportar
+const ThemeContext = createContext();
+function useTheme() {
+ return useContext(ThemeContext);
+}
+export default useTheme;
+
+// Se crea el proveedor para envolver nuestra app,
+// usando como valor un estado para el tema
+// y una función que alterna entre claro y oscuro.
+export function ThemeProvider({ children }) {
+ const [theme, setTheme] = useState("light");
+ const changeTheme = () => {
+ setTheme(theme === "light" ? "dark" : "light");
+ };
+ return (
+
+ {children}
+
+ );
+}
+```
+
+Luego de esto solo queda envolver nuestra aplicación en el proveedor y empezar a usar el contexto en nuestros componentes.
+
+```jsx
+// index.jsx
+import React from "react";
+import ReactDOM from "react-dom/client";
+import App from "./App";
+import { ThemeProvider } from "./ThemeProvider.jsx";
+
+ReactDOM.createRoot(document.getElementById("root")).render(
+
+ {/* El proveedor se usa para envolver el componente raíz de la app */}
+
+
+
+ ,
+);
+```
+
+```jsx
+// App.jsx
+import "./App.css";
+// Importamos el contexto de nuestro tema
+import useTheme from "./ThemeProvider";
+
+export default function App() {
+ // Accedemos al estado del tema y la función que lo cambia
+ const { theme, changeTheme } = useTheme();
+ return (
+
+
Theme {theme}
+
+
+ );
+}
+```
+
+Puedes ver otros usos de la api de contexto en [ésta lección](https://4geeks.com/lesson/context-api). Aquí podemos ver el resultado final en funcionamiento:
+
+
+## Componentes de orden superior (Higher order components - HOC)
+
+Este patrón plantea la creación de componentes que estén diseñados para contener en su interior a otro componente, al mismo tiempo que le agrega funcionalidades. Este componente contenedor, llamado de orden superior, tiene que contemplar funcionalidades comunes que puedan ser requeridas por los demás componentes que serán envueltos con él.
+
+En este ejemplo tenemos un componente de tarjeta (Card) de bootstrap que tiene una funcionalidad básica, pero que implementa el patrón HOC para que recibir otros componentes como cuerpo de dicha tarjeta. Esto permite tener componentes de tarjeta similares, que comparten funcionalidades comunes, pero que tienen una estructura propia para el contenido.
+
+```jsx
+// Card.jsx
+export default function wrapCard(BodyComponent) {
+ const CardWrapper = (props) => {
+ // Esta función será utilizada por todos los componentes envueltos en este
+ const saveClick = () => {
+ console.log("Saved props: " + JSON.stringify(props));
+ };
+ return (
+ <>
+
+
+
+ {/* Barra de herramienta para las tarjetas*/}
+
+
+ {/* Aquí se coloca el componente del cuerpo de la tarjeta*/}
+
+
+ >
+ );
+ };
+ return CardWrapper;
+}
+```
+
+A la hora de crear el componente para el cuerpo se debe exportar llamando a la función que lo va a envolver en el componente de nivel superior.
+
+```jsx
+// Character.jsx
+import wrapCard from "./Card";
+
+const CharacterCard = ({ character }) => {
+ return (
+ <>
+
+ {/* Encabezado de la tarjeta */}
+
+
+ {/* Cuerpo de la tarjeta */}
+
+ >
+ );
+};
+// Se exporta envuelto en el componente de nivel superior
+export default wrapCard(CharacterCard);
+```
+
+Así como este componente pueden crearse todos los que sean necesarios utilizando el patrón HOC para que todos compartan funcionalidades y estilos. Aquí tienes un ejemplo implementando esta tarjeta:
+
+
+
+## Patrón de componentes compuestos (Compound components)
+
+Este patrón plantea la integración de componentes que están hechos para trabajar juntos o muy integrados. Para ello el componente principal crea un contexto y lo expone a los componentes hijos que deben ir dentro, lo que les permite compartir datos y funciones dentro del conjunto. Una librería que implementa este patrón es **React Bootstrap**, que implementa sus formularios como un componente que debe estar integrado por otros subcomponentes para los controles, permitiéndole integrar funciones como la validación de manera conjunta.
+
+Si bien los componentes hijos se declaran como cualquier otro componente, se suelen exportar como miembros del componente principal, para que en implementación sea mas notoria su integración.
+
+```jsx
+// Contexto para el conjunto de componentes
+const SelectContext = createContext();
+
+// Componente principal
+const Select = (props) => {...};
+
+// Componente hijo
+const Option = (props) => {...};
+
+// Se agrega al componente principal una propiedad que contiene al hijo
+Select.Option = Option;
+
+export default Select;
+```
+
+ Para el ejemplo crearemos un selector de opciones para un formulario. El componente padre será `