- [PROPS(propiedades):]
- [REDERIZAR MEDIANTE UN ARREGLO:]
- [RENDERIZAR CONDICIONAL:]
- [STATE(estado):]
- [HOOKS:]
- [EVENTOS:]
- [FORMULARIOS:]
- [CONTROLLED COMPONETS:]
- [UNCONTROLLED COMPONETS:]
- [REFERENCIAS:]
- [LISTAS Y LLAVES:]
- [EJEMPLO:]
PROPS(propiedades):
Las *******props******* son como argumentos que le pasamos a una función. Se los pasa un padre a un hijo.
Es la manera que tienen los componentes para comunicarse entre ellos, es un objeto que contiene propiedades y valores, o alguna propiedad con valor, el cual es enviado como argumento en las funciones que serán componentes, el cual para acceder a dichas *******props*******, se hace como con un objeto:
- Comunicación entre componentes, siendo la comunicación entre el componente padre y el hijo, o viceversa.
- Tienen un flujo de cascada, en ejecución de superior a inferior.
- Podemos mandar cualquier valor(objetos, funciones, string, etc).
- Pueden cambiar a lo largo del tiempo.
- Los componentes de React tienen prohibido mutar las props.
Para enviar los valores de las props:
- Se deben de colocar dentro de la etiqueta que será el componente a ejecutar.
- Se coloca el nombre, el símbolo de asignación y se utilizan llaves, ya que es código de JavaScript.
- Si es un valor de cadena de texto, se pueden omitir las llaves.
- Si será un objeto, se puede colocar el nombre de la variable que contiene el objeto, o dentro de las llaves declarar el objeto con sus propias llaves y colocando las propiedades y valores.
Así un mismo componente puede renderizar(mostrar) algo distinto dependiendo de las *******props(propiedades)******* que se le envíen.
Cuando se tiene un valor que se deduce a partir de una *****prop***** o un *********estado******, se puede guardar en una variable, ya que cada vez que se cambie la **prop***** o el *********estado*********, el componente se va a renderizar así se verá reflejado el cambio en la variable.
children:
Ésta es una *****prop**(propiedad) llamada ********children********, la cual es un ************componente*************** enviado como *****prop/argumento***** a un componente padre para renderizarlo dentro de dicho padre. Similar al contenido dentro de las etiquetas de HTML.
Ésta propiedad le indica a un componente que puede contener elementos hijos, uno o muchos, dependiendo de lo que se requiera.
Dicha *****prop***** es un arreglo de elementos de React.
-
Para enviar dicha *************************prop children**********************, se hace igual que el contenido de una etiqueta HTML, dentro de las etiquetas del llamado a la función componente, se coloca la ****prop children*******, la cual es un componente e igual se coloca como etiqueta HTML.
Para dichas *************************props children***********************, **no es necesario contenerlas dentro de un *************fragment************* o algún contenedor.
-
Para poder recibir dichas *************************props children*************************, se puede:
- Como parámetro, destructurar para obtener acceder directamente a dicha ***prop: {children}***
- Como parámetro, colocar “***props*** y para acceder a dicha *****prop***** children, se hace mediante llaves por ser código de JS dentro de JSX: {props.children}
import PropTypes from "prop-types"; //Se importa la librería PropTypes, desde, "prop-types" que se utiliza para declarar y validar los tipos de las propiedades que se pasan a los componentes
import Avatar from './Avatar'; //Se importa como valor por defecto el componente "Avatar", desde, la ruta del archivo
function Card(**{children}**) { //Declaración de función la cual será un componente, posee un parámetro para recibir la ********prop******** **************children**************, mediante la sintaxis de destructuración para obtener la ********prop******** **************children************** la cual representa los elementos hijos que se encuentran contenidos dentro de un componente, la cual ejecuta el siguiente bloque
return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis
<div className="card"> //Etiqueta contenedora de bloque, posee un selector de clase, y contiene lo siguiente
**{children}** //Dentro de llaves por ser código de JS, se renderiza la **********prop children**********, obtenida desde el argumento(********prop********) envíado al componente "******Card******" al llamarlo para ser renderizado
</div>
);
}
export default function Profile() { //Se exporta como valor por defecto, la declaración de función que será un componente, y que ejecuta el siguiente bloque
return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis
<Card> //El llamado a ejecutar dicho componente, el cual recibe y contiene las siguientes ********props children********
**<h1>Rei Ayanami</h1>** //prop children, que es una etiqueta de título principal, la cual contiene texto
**<Avatar** //prop children, que es el llamado a ejecutar dicha funicón componente, la cual recibe las siguientes props
****size={100} ****//prop enviada al componente, la cual será el tamaño, y que tiene valor en código de JS, colocado entre llaves, el valor numérico 100
****person={{ ****//Propiedad enviada al componente, para los valores necesarios, con valor asignado de, dentro de llaves por ser código de JS, un objeto con las siguiente propiedades
**** name: 'Rei Ayanami', //Propiedad del objeto, con valor de una cadena de texto
imageId: 'YfeOqp2' //Propiedad del objeto, con valor de una cadena de texto
}}
**/>**
</Card>
);
}
Card.propTypes = { //De dicha función componente, se accede a su propiedad estática "propTypes" que es un objeto para especificar los tipos de datos esperados de las propiedades(****props****) de un componente y asegurarse de que sean utilizadas correctamente, el cual es obtenido de la librería "prop-types", y se reasigna su valor para definir las validaciones de tipo para las propiedades person y size del componente "Perfil"
children: PropTypes.array //Se establece que, la propiedad "children" debe, desde la librería "PropTypes", ser un arreglo
};
PropTypes:
Para saber que *******props******* recibe un componente y verificar los tipos de datos de las mismas, se hace uso de PropTypes:
- Para declarar las PropTypes de un componente:
- Se coloca el nombre del componente.
- Se accede a la propiedad propTypes mediante un punto “.”
- Se le asigna como valor un objeto, el cual va a coincidir con el objeto *******props****, colocando la misma estructura de ****props*******.
- A cada propiedad, se le declara de que tipo de dato debe ser, mediante “PropTypes” se coloca el nombre del tipo de dato, y finalmente si es requerido, utilizando “isRequired”.
import **PropTypes** from "prop-types"; //Se importa la librería PropTypes, desde, "prop-types" que se utiliza para declarar y validar los tipos de las propiedades que se pasan a los componentes
ComponentName.**propTypes** = { //De dicha función componente, se accede a su propiedad estática "propTypes" que es un objeto para especificar los tipos de datos esperados de las propiedades(****props****) de un componente y asegurarse de que sean utilizadas correctamente, el cual es obtenido de la librería "prop-types", y se reasigna su valor para definir las validaciones de tipo para las propiedades person y size del componente "Perfil"
person: **PropTypes**.shape({ //La propiedad "person" que es un objeto, se le asigna como valor para validar su tipo de dato requerido, mediante de la librería "PropTypes" importada, ejecutar su método de validador shape(formas) para validar que una propiedad sea un objeto y especificar los tipos de datos de las propiedades dentro de ese objeto, el cual recibe como argumento un objeto para validar los valores de sus propiedades, donde las claves del objeto representan las propiedades del objeto que se está validando, y los valores representan los validadores para esas propiedades
name: **PropTypes.string.isRequired**, //Se establece que, la propiedad "name" debe, desde la librería "PropTypes", ser una cadena de texto, y es requerida
imageId: **PropTypes.string.isRequired** //Se establece que, la propiedad "imageId" debe, desde la librería "PropTypes", ser una cadena de texto, y es requerida
}).**isRequired**, //Asegura que las propiedades especificadas sean requeridas y deben estar presentes cuando se utilice el componente
size: **PropTypes.number.isRequired** //Se establece que, la propiedad "size" debe, desde la librería "PropTypes", ser un valor numérico, y es requerida
};
EJEMPLO:
//main.jsx
import React from 'react'; //Se importa la librería de React, desde, react
import ReactDOM from 'react-dom/client'; //Se importa la librería de react para manupular el DOM, desde, la librería de "react-dom/client"
import App from './App.jsx'; //Se importa como valor por defecto dicho componente, desde, otro módulo mediante su ruta
ReactDOM.createRoot(document.getElementById('root')).render( //Mediante la librería de react para manipular el DOM, se llama a su método para crear una raíz de React que se utilizará como punto de entrada para renderizar los componentes en el DOM, el cual recibe como argumento, del archivo HTML, obtener el elemento mediante su selector identificador el cual es enviado como argumento en cadena de texto, así dicho elemento será el punto de entrada, al que se le aplica el método de la raíz de React que se encarga de renderizar los componentes en el DOM, el cual recibe la siguiente estructura de JSX
<React.StrictMode> //Se utiliza desde la librería de react, el componente para realizar comprobaciones adicionales en desarrollo
<App /> //Se llama a ejecutar dicho componente importado desdes otro módulo, siendo ejecutado como etiqueta HTML para poder ser renderizado
</React.StrictMode>
);
//App.jsx
import Avatar from "./Avatar"; //Se importa como valor por defecto dicho componente, desde, otro módulo mediante su ruta
export default function Profile() { //Se exporta como valor por defecto, la declaración de función que será un componente, el cual ejecuta el siguiente bloque
let user1 = { //Declaración de variable con valor asignado de un objeto, el cual contiene las siguiente propiedades
name: "Rei Ayanami", //Propiedad del objeto, con valor de una cadena de texto
imageId: "YfeOqp2" //Propiedad del objeto, con valor de una cadena de texto
};
return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis
<div> //Etiqueta contenedora de bloque
<Avatar //Se llama a ejecutar dicho componente importado, ejecutado como etiqueta HTML para poder ser renderizado, el cual recibe las siguientes "**props**"
**size={150}** //Propiedad enviada al componente, para el tamaño, con valor asignado de, dentro de llaves por ser código de JS, el valor numérico 150
**person={user1}** //Propiedad enviada al componente, para. los valores necesarios, con valor asignado de, dentro de llaves por ser código de JS, el valor de dicha variable, el cual es un objeto
/>
<Avatar //Se llama a ejecutar dicho componente importado, ejecutado como etiqueta HTML para poder ser renderizado, el cual recibe las siguientes "**props**"
**size={100}** //Propiedad enviada al componente, para el tamaño, con valor asignado de, dentro de llaves por ser código de JS, el valor numérico 100
**person={{** //Propiedad enviada al componente, para los valores necesarios, con valor asignado de, dentro de llaves por ser código de JS, un objeto con las siguiente propiedades
**name: "Azuka Langley",** //Propiedad del objeto, con valor de una cadena de texto
**imageId: "OKS67lh"** //Propiedad del objeto, con valor de una cadena de texto
**}}**
/>
<Avatar //Se llama a ejecutar dicho componente importado, ejecutado como etiqueta HTML para poder ser renderizado, el cual recibe las siguientes "**props**"
**size={50}** //Propiedad enviada al componente, para el tamaño, con valor asignado de, dentro de llaves por ser código de JS, el valor numérico 50
**person={{** //Propiedad enviada al componente, para. los valores necesarios, con valor asignado de, dentro de llaves por ser código de JS, un objeto con las siguiente propiedades
**name: "Shinji Ikari",** //Propiedad del objeto, con valor de una cadena de texto
**imageId: "1bX5QH6"** //Propiedad del objeto, con valor de una cadena de texto
**}}**
/>
</div>
);
}
//Avatar.jsx
import PropTypes from "prop-types"; //Se importa la librería PropTypes, desde, "prop-types" que se utiliza para declarar y validar los tipos de las propiedades que se pasan a los componentes
export default function Avatar(props) { //Se exporta como valor por defecto, la declaración de función que será un componente, el cual posee un parámetro para recibir las "props"(propiedades) en un objeto, la cual ejecuta el siguiente bloque
return <Perfil {...props} />; //Se retorna la ejecución de dicho componente ejecutado como etiqueta HTML para poder ser renderizado, el cual recibe sus "props"(propiedades) desde dicho objeto enviado como argumento a la función, utilizando la sintaxis de "propagación" para pasar todas las propiedades de dicho objeto
}
function Perfil({ person, size }) { //Declaración de función que será un componente, el cual recibe mediante la sintaxis de "destructuración", dos argumentos que serán obtenidos desde un objeto "props"(propiedades), para acceder a las propiedades con dichos nombres, así evitando mutar dicho objeto ya que así se crear variable con el nombre declarado en la "destructuración" solo obtenido los valores del objeto
let {name, imageId} = person; //Declaración de variable que destructura las propiedades "name" e "imageId", del objeto "person", que también fue destructurado desde el objeto "props" que se le envía como argumento a la función componente
let image = "../public/rei.webp"; //Declaración de variable con valor asignado de, una cadena de texto la cual es una ruta para obtener una imagen
return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis
<img //Etiqueta de imagen, la cual posee los siguiente
className="avatar" //Selector de clase con sintaxis camelCase, con valor de, una cadena de texto
src={image} //Atributo de "fuente", con valor de, el valor de dicha variable, siendo colocado dentro de llaves por ser código de JS
alt={name} //Atributo de "alternativo" para cuando no pueda ser mostrada la imagen, con valor de, de dicho argumento destructurado en el parámetro de la función el cual es un objeto, acceder al valor de su propiedad "name", siendo colocado dentro de llaves por ser código de JS
width={size} //Atributo de ancho, con valor de, el valor de dicho argumento destructurado en el parámetro de la funció, siendo colocado dentro de llaves por ser código de JS
height={size} //Atributo de alto, con valor de, el valor de dicho argumento destructurado en el parámetro de la funció, siendo colocado dentro de llaves por ser código de JS
/>
);
}
Perfil.propTypes = { //De dicha función componente, se accede a su propiedad estática "propTypes" que es un objeto para especificar los tipos de datos esperados de las propiedades(****props****) de un componente y asegurarse de que sean utilizadas correctamente, el cual es obtenido de la librería "prop-types", y se reasigna su valor para definir las validaciones de tipo para las propiedades person y size del componente "Perfil"
person: PropTypes.shape({ //La propiedad "person" que es un objeto, se le asigna como valor para validar su tipo de dato requerido, mediante de la librería "PropTypes" importada, ejecutar su método de validador shape(formas) para validar que una propiedad sea un objeto y especificar los tipos de datos de las propiedades dentro de ese objeto, el cual recibe como argumento un objeto para validar los valores de sus propiedades, donde las claves del objeto representan las propiedades del objeto que se está validando, y los valores representan los validadores para esas propiedades
name: PropTypes.string.isRequired, //Se establece que, la propiedad "name" debe, desde la librería "PropTypes", ser una cadena de texto, y es requerida
imageId: PropTypes.string.isRequired //Se establece que, la propiedad "imageId" debe, desde la librería "PropTypes", ser una cadena de texto, y es requerida
}).isRequired, //Asegura que las propiedades especificadas sean requeridas y deben estar presentes cuando se utilice el componente
size: PropTypes.number.isRequired //Se establece que, la propiedad "size" debe, desde la librería "PropTypes", ser un valor numérico, y es requerida
};
REDERIZAR MEDIANTE UN ARREGLO:
Para renderizar elementos mediante un arreglo:
- Se hace uso de la función *******map()*******, la cual será aplicada al arreglo a ser iterado y la cual recibirá una función para rendererizar elementos que usen los valores dentro del arreglo.
let **frutas** = [ //Declaración de variable con valor asigando de, un arreglo con varios valores de cadena de texto
"banana",
"pera",
"manzana",
"uva",
"sandía",
"cereza"
];
export default function ListaFrutas() { //Se exporta como valor por defecto, la declaración de función que será un componente, la cual ejecuta el siguiente bloque
function renderizarFruta(**fruta**) { //Declaración de función anidada, la cual posee un parámetro para recibir como argumento cada uno de los valores dentro del arreglo a ser iterado con map, y que ejecuta el siguiente bloque
return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis
**<li key={fruta}>{fruta}</li>** //Etiqueta de elemento listado, la cual posee la propiedad "******key******" necesaria cuando se renderizan listas de elementos para que React pueda identificarlos de manera única y optimizar el proceso de actualización, con valor del mismo valor enviado como argumento a la función "renderizarFruta", siendo dicho elemento listado contiene dentro de llaves por ser código de JS el valor enviado como argumento a la función "renderizarFruta", así por cada valor dentro del arreglo
)
}
return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis
<div> //Etiqueta contenedora de bloque, la cual contiene lo siguiente
<h2>Las frutas que hay son:</h2> //Etiqueta de subtítulo, el cual contiene texto
<ul>**{frutas.map(renderizarFruta)}**</ul> //Etiquta de lista desordenada, la cual contiene entro de llaves por ser código de JS, a dicho arreglo "frutas", aplica el método de "crear un nuevo arreglo con cambios" el cual recibe como argumento, la función renderizarFruta, la cual retorna un elemento listado por cada uno de os valores dentro del arreglo "frutas"
</div>
)
}
RENDERIZAR CONDICIONAL:
En react cuando se necesita renderizar componentes de manera condicional, se hace:
- Dentro de llaves por ser código de JS “*{ }*”.
- Se coloca la condición a cumplir.
- Se coloca el operador and(&&).
-
Finalmente se llama a ejecutar el componente cómo etiqueta HTML, ***.***
const [**show**, setShow] = useState(**true**); //Declaración de constante la cual será un estado del componente, en la cual se utiliza la sintaxis de destructuración de arreglos, siendo el primer valor, el valor actual del estado el cual empieza siendo el valor por defecto enviado a "useState", y como segundo valor la función que actualizará el estado, dicha constante tiene valor asignado de, llamar a ejecutar la función importada para el estado del componente, la cual recibe como argumento para el valor por defecto del componente, el valor booleano true return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis <div> //Etiqueta contenedora de bloque **{show && <Component />}** //Dentro de llaves por ser código de JS, se valida la condición de que si "**show**" que es el valor actual del estado del componente tiene valor "true", mediante el operador and(&&), llamar a ejecutar dicho otro componente como etiqueta de HTML para ser renderizado, de lo contrario no se hace nada </div> )
También se puede utilizar el operador ternario:
- Dentro de llaves por ser código de JS “*{ }*”.
- Se coloca la condición a cumplir.
- Se coloca el símbolo “?”.
- Finalmente se llama a ejecutar el componente como etiqueta HTML, ***.***
- Se coloca el símbolo “:”.
-
Y finalmente se coloca el caso en que no se cumpla la condición.
const [**show**, setShow] = useState(**true**); //Declaración de constante la cual será un estado del componente, en la cual se utiliza la sintaxis de destructuración de arreglos, siendo el primer valor, el valor actual del estado el cual empieza siendo el valor por defecto enviado a "useState", y como segundo valor la función que actualizará el estado, dicha constante tiene valor asignado de, llamar a ejecutar la función importada para el estado del componente, la cual recibe como argumento para el valor por defecto del componente, el valor booleano true ****return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis <div> //Etiqueta contenedora de bloque **{show ? <Component /> : null}** //Dentro de llaves por ser código de JS, se valida la condición de que si "**show**" que es el valor actual del estado del componente tiene valor "true", mediante el operador ternario(? :), llamar a ejecutar dicho otro componente como etiqueta de HTML para ser renderizado, de lo contario, si su valor es "false", se retorna "nulo", para no renderizar nada </div> )
STATE(estado):
El estado es como la memoria de un componente. El componente debe “recordar” esto.
- El estado solo se puede usar en funciones que serán componentes.
- El estado no se muta directamente, sino que lo actualizamos mediante una función.
- Es donde un componente guarda cierta información y la puede cambiar como respuesta a interacciones.
- Se pueden tener más de un solo estado en un componente.
- useState() es una función que se importa desde la librería de React, la cual recibe como argumento un valor por defecto.
-
useState() retorna un arreglo de elementos, el cual para acceder a ellos es necesario la sintaxis de *****************************destructuración:*****************************
- Siendo el primer valor, el valor actual del estado.
- Como segundo valor, se retorna una función, la cual al ser llamada y enviarle un valor como argumento, hará la actualización del estado y dicho valor enviado como argumento será el nuevo valor del estado y será el que se mostrará siendo renderizado.
import { **useState** } from "react"; //Se importa la función hook "useState", desde la librería de react, para agregar el estado a los componentes
export default function App() { //Se exporta como valor por defecto, la declación de función que será un componente, la cual ejecuta el siguiente bloque
return( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis
<div> //Contenedor de bloque
<Counter /> //Se llama a ejecutar dicho componente importado, ejecutado como etiqueta HTML para poder ser renderizado
</div>
);
}
function Counter() { //Declaración de función que será un componente, la cual ejecuta el siguiente bloque
**const [age, setAge] = useState(0)**; //Declaración de constante la cual será un estado del componente, en la cual se utiliza la sintaxis de destructuración de arreglos, siendo el primer valor, el valor actual del estado el cual empieza siendo el valor por defecto enviado a "useState", y como segundo valor la función que actualizará el estado, dicha constante tiene valor asignado de, llamar a ejecutar la función importada para el estado del componente, la cual recibe como argumento para el valor por defecto del componente, el valor numérico "0"
**const [name, setName] = useState("Name")**; //Declaración de constante la cual será un estado del componente, en la cual se utiliza la sintaxis de destructuración de arreglos, siendo el primer valor, el valor actual del estado el cual empieza siendo el valor por defecto enviado a "useState", y como segundo valor la función que actualizará el estado, dicha constante tiene valor asignado de, llamar a ejecutar la función importada para el estado del componente, la cual recibe como argumento para el valor por defecto del componente, el valor numérico "Name"
function inputContent() { //Declaración función, la cual ejecuta el siguiente bloque
let input = document.querySelector(".name"); //Declaración de variable con valor asignado de, del documento HTML, obtener el primer elemento mediante su selector, el cual es el de clase enviado como cadena de texto
return input.value; //Se retorna, del elemento obtenido mediante su selector, su valor ingresado
}
return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis
<div className="counter"> //Contendor de bloque, posee un selector de clase
<h1>My age is: {**age**} years old</h1> //Etiqueta de título pricipal, la cual contiene texto y dentro de llaves por ser código de JS, el valor de "age" el cual es uno de los valores actuales del componente
<button onClick={() => **setAge(age + 1)**}>Sumar uno</button> //Etiqueta de botón, el cual recibe como "prop"(propiedad) siendo un atributo, el manejador de eventos en respuesta a un clic del mouse en el botón, con valor asignado de, dentro de llaves por ser código de JS, una función de flecha, la cual llama a ejecutar la función de actualización del estado la cual recibe como argumento, el valor actual del componente("age") y se le suma el valor numérico 1, siendo el resultado, el nuevo valor actual del compente, y dicha etiqueta contiene texto
<button onClick={() => **setAge(age - 1)**}>Restar uno</button> //Etiqueta de botón, el cual recibe como "prop"(propiedad) siendo un atributo, el manejador de eventos en respuesta a un clic del mouse en el botón, con valor asignado de, dentro de llaves por ser código de JS, una función de flecha, la cual llama a ejecutar la función de actualización del estado la cual recibe como argumento, el valor actual del componente("age") y se le resta el valor numérico 1, siendo el resultado, el nuevo valor actual del componente, y dicha etiqueta contiene texto
<button onClick={() => **setAge(age + 10)**}>Sumar diez</button> //Etiqueta de botón, el cual recibe como "prop"(propiedad) siendo un atributo, el manejador de eventos en respuesta a un clic del mouse en el botón, con valor asignado de, dentro de llaves por ser código de JS, una función de flecha, la cual llama a ejecutar la función de actualización del estado la cual recibe como argumento, el valor actual del componente("score") y se le suma el valor numérico 10, siendo el resultado, el nuevo valor actual del componente, y dicha etiqueta contiene texto
<button onClick={() => **setAge(age - 10)**}>Restar diez</button> //Etiqueta de botón, el cual recibe como "prop"(propiedad) siendo un atributo, el manejador de eventos en respuesta a un clic del mouse en el botón, con valor asignado de, dentro de llaves por ser código de JS, una función de flecha, la cual llama a ejecutar la función de actualización del estado la cual recibe como argumento, el valor actual del componente("age") y se le resta el valor numérico 10, siendo el resultado, el nuevo valor actual del componente, y dicha etiqueta contiene texto
<h1>My name is: {**name**}</h1> //Etiqueta de título pricipal, la cual contiene texto y dentro de llaves por ser código de JS, el valor de "name" el cual es uno de los valores actuales del componente
<input type="text" className="name"/> //Etiqueta de ingreso de datos, la cual recibe como "prop"(propiedad) siendo un atributo, el tipo de ingreso de datos con valor de texto, y posee un selctor de clae
<button onClick={() => **setName(inputContent)**}>Establecer</button> //Etiqueta de botón, el cual recibe como "prop"(propiedad) siendo un atributo, el manejador de eventos en respuesta a un clic del mouse en el botón, con valor asignado de, dentro de llaves por ser código de JS, una función de flecha, la cual llama a ejecutar la función de actualización del estado la cual recibe como argumento, la función para obtener el valor del input siendo el retorno de la misma, el nuevo valor actual del componente, y dicha etiqueta contiene texto
</div>
);
}
- Al cambiar el estado, React detecta que hubo cambios y hay que reflejarlos en la pantalla, renderizándolos.
- Si lo que se necesita para hacer un nuevo render con una variable que cambie a lo largo de tiempo, lo necesario es el ***********state(estado).*********** React no renderiza las mutaciones de las variables porque no detecta dichos cambios.
- React junta todos los cambios en los estados, los realiza y el estado cambio y finalmente los renderiza todos juntos.
El hook useState() es esencial para crear componentes funcionales con estado en React, lo que te permite mantener la coherencia y reactividad en tu aplicación mientras manipulas y actualizas datos de manera sencilla.
HOOKS:
Los hooks son funciones que en general comienzan con *****use*****, y permiten reutilizar código. Algunas son:
- useState(): Para manejar el estado de los componentes y renderizar los cambios respecto al cambio del estado.
- useEffect(): Para manejar los efectos secundarios de los componentes respecto a cambio de valor de una propiedad del componente.
- useRef(): Para ****acceder directamente al elemento HTML mediante el DOM. Las referencias no provocan una actualización del componente cuando cambian su valor, y tampoco provocan una nueva renderización.
- useImperativeHandle(): Permite pasar y acceder a la referencia de un elemento del DOM.
REGLAS:
- No puede estar dentro de un condicional if.
- Se tienen que llamar en el top-level(parte superior) del componente.
- Solo se puede invocar en funciones que serán componentes (o en otros hooks).
useEffect(function, [ , ]):
- Se usa para realizar efectos secundarios en un componente.
- Se ejecuta luego de los cambios del DOM.
-
Recibe dos argumentos:
- Una función: Ésta función puede no retornar nada o retornar a su vez otra función, la cual es llamada “clean up”, porque suele “limpiar” acciones y es la última en ser ejecutada.
-
Un array de dependencias (opcional): Puede ser un arreglo vacío o un arreglo con dependencias:
- Si no se recibe dicho arreglo, el efecto se va a ejecutar cada vez que se renderice el componente.
- Si se recibe un arreglo vacío, el efecto se va a ejecutar la primera y última vez que se renderice el componente.
- Se se recibe un arreglo con dependencias, el efecto se va a ejecutar cada vez que cambie algún elemento del arreglo de dependencias.
Dichas dependencias son valores son valores que están relacionadas con los componentes, las cuales pueden ser modificadas y cambiar con el tiempo, pueden ser “*******props*******” enviadas al componente.
-
Se recomienda el uso de ***************useEffect*************** cuando:
- Se necesita agregar un “listener”(escuchador).
- Que se requiera hacer algo cuando se cambie el valor de una “*****prop*****” del componente.
EJEMPLO:
import { useState } from "react"; //Se importa la función hook para manejar el estadoo en componentes, desde, la libreriía de react
**import { useEffect } from "react";** //Se importa la función hook para manejar efectos secundarios en componentes, desde, la libreriía de react
import PropTypes from "prop-types"; //Se importa la librería PropTypes, desde, "prop-types" que se utiliza para declarar y validar los tipos de las propiedades que se pasan a los componentes
export default function App() { //Se exporta como valor por defecto, la declaración de función que será un componente, la cual ejecuta el siguiete bloque
const [show, setShow] = useState(true); //Declaración de constante la cual será un estado del componente, en la cual se utiliza la sintaxis de destructuración de arreglos, siendo el primer valor, el valor actual del estado el cual empieza siendo el valor por defecto enviado a "useState", y como segundo valor la función que actualizará el estado, dicha constante tiene valor asignado de, llamar a ejecutar la función importada para el estado del componente, la cual recibe como argumento para el valor por defecto del componente, el valor booleano "true"
const [counter, setCounter] = useState(0); //Declaración de constante la cual será un estado del componente, en la cual se utiliza la sintaxis de destructuración de arreglos, siendo el primer valor, el valor actual del estado el cual empieza siendo el valor por defecto envuiado a "useState", y como segundo valor la función que actualizará el estado, dicha constante tiene valor asignado de, llamar a ejecutar la función importada para el estado del componente, la cual recibe como argumento para el valor por defecto del componente, el valor numérico "0"
function open() { //Declaración de función para mostrar un elemento en el DOM, la cual ejecuta el siguiente bloque
setShow(true); //Se llama a ejecutar la función de actualización del estado la cual recibe como argumento, el valor booleano "true"
}
function close() { //Declaración de función para ocultar un elemento en el DOM, la cual ejecuta el siguiente bloque
setShow(false); //Se llama a ejecutar la función de actualización del estado la cual recibe como argumento, el valor booleano "false"
}
function addCounter() { //Declaración de función para modificar el valor de un estado del componente, la cual ejecuta el siguiente bloque
setCounter(counter + 1); //Se llama a ejecutar la función de actualización del estado la cual recibe como argumento, el valor actual del dicho estado, y se le suma el valor numérico 1, siendo el resultado el nuevo valor actual del componente
}
function removeCounter() { //Declaración de función para modificar el valor de un estado del componente, la cual ejecuta el siguiente bloque
setCounter(counter - 1); //Se llama a ejecutar la función de actualización del estado la cual recibe como argumento, el valor actual del dicho estado, y se le resta el valor numérico 1, siendo el resultado el nuevo valor actual del componente
}
return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis
<div className="app"> //Etiqueta contenedora de bloque, la cual recibe una "prop" que es un selector de clase, con valor de una cadena de texto
<button onClick={open}>Abrir</button> //Etiqueta de botón, el cual recibe como "prop"(propiedad) siendo un atributo, el manejador de eventos en respuesta a un clic del mouse en el botón, con valor asignado de, dentro de llaves por ser código de JS, llamar a la función para mostrar un elemento en el DOM, y dicho botón contiene texto
<button onClick={close}>Cerrar</button> //Etiqueta de botón, el cual recibe como "prop"(propiedad) siendo un atributo, el manejador de eventos en respuesta a un clic del mouse en el botón, con valor asignado de, dentro de llaves por ser código de JS, llamar a la función para ocultar un elemento en el DOM, y dicho botón contiene texto
{show && <Cartel />} //Dentro de llaves por ser código de JS, se valida la condición de que si "show" que es el valor actual del estado del componente tiene valor "true", mediante el operador and(&&), llamar a ejecutar dicho otro componente como etiqueta de HTML para ser renderizado, de lo contrario no se hace nada
<button onClick={addCounter}>Sumar al contador</button> //Etiqueta de botón, el cual recibe como "prop"(propiedad) siendo un atributo, el manejador de eventos en respuesta a un clic del mouse en el botón, con valor asignado de, dentro de llaves por ser código de JS, llamar a la función para modificar el valor de un estado del componente, y dicho botón contiene texto
<button onClick={removeCounter}>Restar al contador</button> //Etiqueta de botón, el cual recibe como "prop"(propiedad) siendo un atributo, el manejador de eventos en respuesta a un clic del mouse en el botón, con valor asignado de, dentro de llaves por ser código de JS, llamar a la función para modificar el valor de un estado del componente, y dicho botón contiene texto
<Elemento show={show} counter={counter}/> //Se llama a ejecutar dicho compoente como etiqueta de HTML para ser renderizado, el cual recibe dos "props", ambas propiedades son el valor de cada uno de los estados del compoente, para poder acceder a ellos
</div>
);
}
function Elemento(props) { //Declación de función, la cual posee un argumento para reibir el objeto "props", y que ejecuta el siguiente bloque
**useEffect(efecto, [props.show]);** //Se llama a ejecutar la función hook para manejar efectos secundarios en componentes, la cual recibe como primer argumento, una función a ser ejecutada cada vez que haya algún cambio en el segundo parámetro, el cual es un arreglo que contiene, del objeto "props", acceder a la propiedad "show" la cual es el estado actual del componente "App"
let esMayorA5 = props.counter > 5; //Declaración de variable con valor asignado de, del del objeto "props", acceder a la propiedad "counter" la cual es el estado actual del componente "App", y validar si es mayor que el valor numérico 5, así funcionando como una condicional
**function efecto() {** //Declaración de función, la cual será la función que manejará los efectos secundarios del componente, y que ejecuta el siguiente bloque
console.log("Se ejecuta efecto"); //Llamado a la consola del navegador, a la que se le aplica el método de imprimir sobre la misma, al cadena de texto enviada como argumento
return despedida //Retorna el llamado de dicha función, la cual es un "clean up"
**}**
function despedida() { //Declaración de función que será el "clean up" del efecto secundario del componente, y que ejecuta el siguiente bloque
console.log("Se ejecuta despedida"); //Llamado a la consola del navegador, a la que se le aplica el método de imprimir sobre la misma, al cadena de texto enviada como argumento
}
return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis
<div> //Etiqueta contenedora de bloque
<p>La prop show vale: {**props.show** ? "true" : "false"}</p> //Etiqueta de párrafo, la cual contiene texto, y dentro de llaves por ser código de JS, una condicional de operador ternario, la cual valida, desde el objeto "props", acceder a la propiedad "show" la cual es el estado actual del componente "App", y si su valor actual es el valor booleano "true", se muestra "true", de lo contrario si es valor es el valor booleano "false", se muestra "false"
<p>La prop counter vale: {props.counter}</p> //Etiqueta de párrafo, la cual contiene texto, y dentro de llaves por ser código de JS, del objeto "counter", acceder a la propiedad "show" la cual es el estado actual del componente "App"
{esMayorA5 && <p>Y es mayor que 5</p>} //Dentro de llaves por ser código de JS, se valida la condición de que si el valor de la variable "esMayorA5" la cual es una condicional, mediante el operador and(&&), renderizar la etiqueta de párrafo la cual contiene texto, de lo contrario no se hace nada
</div>
);
}
function Cartel() { //Declación de función, la cual ejecuta el siguiente bloque
**useEffect(efecto, []);** //Se llama a ejecutar la función hook para manejar efectos secundarios en componentes, la cual recibe como primer argumento, una función a ser ejecutada dependiente del segundo parámetro, el cual es un arreglo vacío, provocando que la función sea ejecutada la primera y última vez que se renderice el componente
**function efecto() {** //Declaración de función, la cual será la función que manejará los efectos secundarios del componente, y que ejecuta el siguiente bloque
console.log("Primer render"); //Llamado a la consola del navegador, a la que se le aplica el método de imprimir sobre la misma, al cadena de texto enviada como argumento
return despedida //Retorna el llamado de dicha función, la cual es un "clean up"
**}**
function despedida() { //Declaración de función que será el "clean up" del efecto secundario del componente, y que ejecuta el siguiente bloque
console.log("Último render"); //Llamado a la consola del navegador, a la que se le aplica el método de imprimir sobre la misma, al cadena de texto enviada como argumento
}
return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis
<div> //Etiqueta contenedora de bloque
<p>Soy un cartel</p> //Etiqueta de párrafo, la cual contiene texto
</div>
)
}
Elemento.propTypes = { //De dicha función componente, se accede a su propiedad estática "propTypes" que es un objeto para especificar los tipos de datos esperados de las propiedades(props) de un componente y asegurarse de que sean utilizadas correctamente, el cual es obtenido de la librería "prop-types", y se reasigna su valor para definir las validaciones de tipo para las propiedades "show" y "counter" del componente "Elemento"
show: PropTypes.bool, //Se establece que, la propiedad "show" debe, desde la librería "PropTypes", ser un valor booleano
counter: PropTypes.number //Se establece que, la propiedad "counter" debe, desde la librería "PropTypes", ser un valor numérico
}
EVENTOS:
Los eventos son interacciones que suceden sobre elementos dentro del HTML, Cuando usamos Javascript en páginas de HTML, Javascript puede “reaccionar” sobre estos eventos y así poder darle algún comportamiento.
Algunos de los los eventos más comunes son:
- Click Events
- Form Events
- Keyboard Events
- Mouse Events
EVENT BUBBLING:
Este proceso inicia cuando un elemento ha ejecutado el evento y este se propaga en cadena dentro de los elementos que se contienen dentro de la jerarquía, empezando desde el elemento hijo más profundo y siendo desencadenados los eventos del mismo tipo.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div **onclick="alert('div')"**> <!--Etiqueta contenedora de bloque, la cual posee como atributo, el manejador de eventos de click sobre el elemento, con valor de, ejecutar código de JS el cual es llamar a ejecutar la función de de ventana emergente, la cual muestra la cadena de texo enviada como argumento-->
<p **onclick="alert('p')"**> <!--Etiqueta de párrafo, la cual posee como atributo, el manejador de eventos de click sobre el elemento, con valor de, ejecutar código de JS el cual es llamar a ejecutar la función de de ventana emergente, la cual muestra la cadena de texo enviada como argumento-->
<button **onclick="handleClick()"**>Click me</button> <!--Etiqueta de botón, la cual posee como atributo, el manejador de eventos de click sobre el elemento, con valor de, jecutar código de JS el cual es llamar a ejecutar dicha función desde el archivo de JS-->
</p>
</div>
</div>
<script src="./main.js"></script>
</body>
</html>
function **handleClick**() { //Declaración de función, la cual ejecuta el siguiente bloque
alert("button"); //Llamado a ejecutar la función de ventana emergente, la cual muestra la cadena de texto enviada como argumento
}
-
Para evitar la propagación de los eventos se utiliza la función *********************stopPropagation().*********************
<div onclick="alert('div')"> <!--Etiqueta contenedora de bloque, posee la propiedad manejadora de eventos de hacer click sobre el elementos, con valor asignado de, dentro de comillas ejeuctar código de JS, siendo la función de ventana emergente, la cual muestra la cadena de texto enviada como argumento--> <p onclick="**event.stopPropagation();** <!--Propiedad de manejador de eventos de click sobre el elemento, con valor de ejecutar código de JS, el cual es, al evento ejecutado el cual es el click sobre el elemento, se le aplica el método de detener la propagación del evento en la jerarquía, para solo ejecutarse en este elemento--> alert('p')"> <button onclick=**"handleClick(event)**"> <!--Propiedad de manejador de eventos de click sobre el elemento, con valor de ejecutar código de JS, el cual es, el llamado a ejecutar dicha dicha función desde el archivo de JS, a la cual se el envía el evento ejecutado como argumento--> </button> </p> </div>
```jsx
function **handleClick**(**event**) { //Declaración de función, recibe como argumento el evento ejecutado, la cual ejecuta el siguiente bloque
**event.stopPropagation();** //A dicho evento ejecutado, se le aplica el método de detener la propagación del mismo en la jerarquía, para solo ejecutarse en este elemento
alert("button"); //Llamado a ejecutar la función de ventana emergente, la cual muestra la cadena de texto enviada como argumento
}
```
SYNTHETIC EVENT:
Ya que cada navegador tiene un comportamiento distinto de como funcionan lo eventos, a pesar de que dichos eventos sean muy similares algunos navegadores poseen propiedades que otros no, esto genera mucha inconsistencia, teniendo que crear una lógica para cada uno de los navegadores.
- Es una implementación ***************************cross-browser*************************** por arriba de los eventos nativos del navegador.
- Normaliza los eventos para que las propiedades de los eventos sean consistentes en en diferentes navegadores.
Dentro de dicha funcionalidad hay distintos tipos de atributos que vienen incluidos dentro de éste evento sintético, pero sin contener todas las propiedades de un evento nativo dentro del navegador, para ello se puede utiliza el atributo: DOMEvent nativeEvent.
NOMALIZACIÓN:
Para normalizar se utiliza siempre *******lower camelCase*******, lo cual es que la primer palabra se coloca en minúsculas y las siguientes palabras comenzarán en mayúsculas.
-
Para acceder a un evento en react, se hace directo en la etiqueta HTML de JSX con los atributos de manejadores de eventos, los cuales utilizan la sintaxis *******lower camelCase*******.
//JS function handleClick() { //Declaración de función, la cual ejecuta el siguiente bloque alert("button"); //Llamado a ejecutar la función de ventana emergente, la cual muestra la cadena de texto enviada como argumento } //React <button **onClick=**"handleClick**"**>Click me</button> //Etiqueta HTML JSX de botón, el cual posee como atributo el evento sentético de click sobre el elemento, con valor de llamar a dicha función anterior
FORMULARIOS:
Los formularios en HTML tienen comportamientos por defecto en los navegadores y en muchos casos se requiere evitar dichos comportamientos por defecto para crear una propia funcionalidad de manera manual.
Para prevenir los comportamientos por defecto al enviar los formularios:
-
Al evento ***********onsubmit*********** del formulario *************************se le aplica el método **preventDefault()*****.
<form action="" method="post" **onsubmit="event.preventDefault()**"> <!--Eiqueta de formulario, la cual posee los atributos de "acción" para la petición a la ruta web, el de "método" con valor para "publicar", y el manejador de eventos de "entregar" los datos del formulario con valor de código de JS de hacer referencia al evento ejecutado, y aplicar el método para prevenir el comportamiento por defecto de dicho evento de "entregar"--> <div> <!--Etiqueta contenedora de bloque,--> <label for="name">Name</label> <!--Etiqueta para etiquetar elementos de interfaz de usuario, posee el atributo "for" para enlazarla con el elemento correspondiente con valor de una cadena de texto la cual es la misma que el identificador del elemento a ser enlazado, y contiene texto--> <input type="text" name="name" id="name"> <!--Etiqueta de ingreso de datos, posee los atributo de "tipo" con valor para ser de texto, el de "nombre" que es el nombre del control, el cual es enviado con los datos del formulario, y un selector "identificador" el cual lo enlazará con el label correspondiente--> </div> <div> <!--Etiqueta contenedora de bloque,--> <label for="email">Email</label> <!--Etiqueta para etiquetar elementos de interfaz de usuario, posee el atributo "for" para enlazarla con el elemento correspondiente con valor de una cadena de texto la cual es la misma que el identificador del elemento a ser enlazado, y contiene texto--> <input type="email" name="email" id="email"> <!--Etiqueta de ingreso de datos, posee los atributo de "tipo" con valor para ser de email, el de "nombre" que es el nombre del control, el cual es enviado con los datos del formulario, y un selector "identificador" el cual lo enlazará con el label correspondiente--> </div> <div> <!--Etiqueta contenedora de bloque--> <button>Send</button> <!--Etiqueta de botón, contiene texto--> </div> </form>
CONTROLLED COMPONETS:
Éstos componentes son aquellos que pueden mantener su propio estado y la funcionalidad es ejecutada por React. Dichos componentes son controlados por completo directamente por la lógica que se les aplique, mediante las propiedades enviadas al componente o la funcionalidad de React.
- Se recomienda controlar los formularios.
**import { useState } from "react";** //Se importa la función "useState", desde la librería de react
export default function App() { //Se exporta como valor por defecto, la declaración de función que será un componente JSX
**const [name, setName] = useState('name');** //Declaración de constante la cual será un estado del componente, en la cual se utiliza la sintaxis de destructuración de arreglos, siendo el primer valor, el valor actual del estado el cual empieza siendo el valor por defecto enviado a "useState", y como segundo valor la función que actualizará el estado, dicha constante tiene valor asignado de, llamar a ejecutar la función importada para el estado del componente, la cual recibe como argumento para el valor por defecto del componente, la cadena de texto "name"
**const [email, setEmail] = useState('email');** //Declaración de constante la cual será un estado del componente, en la cual se utiliza la sintaxis de destructuración de arreglos, siendo el primer valor, el valor actual del estado el cual empieza siendo el valor por defecto enviado a "useState", y como segundo valor la función que actualizará el estado, dicha constante tiene valor asignado de, llamar a ejecutar la función importada para el estado del componente, la cual recibe como argumento para el valor por defecto del componente, la cadena de texto "email"
**const handleSubmit = (e) => {** //Declaración de constante con valor asignado de, una función de flecha que recibe como argumento un evento ejecutado, así conviertiendo dicha constante en una función que adopta su nombre declarado, y que ejecuta el siguiente bloque
**e.preventDefault();** //A dicho evento enviado a la función, se le aplica el método para prevenir el comportamiento por defecto de dicho evento
**if (name === '' || email === '') {** //Condicional que valida si, el valor actual del estado "name" es estrictamente igual que una cadena vacía, o si el valor actual del estado "email" es estrictamente igual que una cadena vacía, se ejecuta el siguiente bloque
**alert('Falta algún campo');** //Se ejecuta la función de ventana emergente, la cual muestra la cadena de texto envida como argumento
**return** //No se retorna nada para detener la ejecución
**}
console.log(name, email);** //LLamado a la consola del navegador, a la que se le aplica el método de imprimir sobre la misma, el valor actual del estado "name", y el valor actual del estado "email"
**};**
return ( //Se retorna dentro de paréntesis por ser un componente JSX
<div> //Etiqueta contenedora de bloque
<form onSubmit={**handleSubmit**}> //Eiqueta de formulario, la cual posee el atributo manejador de eventos de "entregar" los datos del formulario con valor de código de JS entre llaves de llamar a dicha función y ejecutarla cuando se ejecute el dicho evento
<div> //Etiqueta contenedora de bloque
<label htmlFor="name">Name</label> //Etiqueta para etiquetar elementos de interfaz de usuario, posee el atributo "htmlFor" para enlazarla con el elemento correspondiente con valor de una cadena de texto la cual es la misma que el identificador del elemento a ser enlazado, y contiene texto
<input //Etiqueta de ingreso de datos, posee los siguientes atributos
value={name} //Atributo de "valor" con valor, dentro de llaves por ser código de JS, de el valor actual de uno de los estados del componente
type="text" //Atributo de "tipo" con valor, para ser de texto
name="name" //Atributo de "nombre" con valor, que es el nombre del control el cual es enviado con los datos del formulario
id="name" //Selector identificador el cual lo enlazará con el label correspondiente
**onChange={(e) => setName(e.target.value)}** //"prop"(propiedad) ****tributo manejador de eventos de "cambio de valor", con valor de ejecutar código de JS entre llaves, ejecutando una función flecha que recibe como argumento dicho evento ejecutado, la cual llama a ejecutar la función de actualización del estado la cual recibe como argumento, del evento ejecutado acceder al elemento que lo ejecutó y obtener su valor, siendo dicho valor el nuevo valor actual del compente
/>
</div>
<div> //Etiqueta contenedora de bloque
<label htmlFor="email">Email</label> //Etiqueta para etiquetar elementos de interfaz de usuario, posee el atributo "htmlFor" para enlazarla con el elemento correspondiente con valor de una cadena de texto la cual es la misma que el identificador del elemento a ser enlazado, y contiene texto
<input //Etiqueta de ingreso de datos, posee los siguientes atributos
value={email} //Atributo de "valor" con valor, dentro de llaves por ser código de JS, de el valor actual de uno de los estados del componente
type="email" //Atributo de "tipo" con valor, para ser de correo electrónico
name="email" //Atributo de "nombre" con valor, que es el nombre del control el cual es enviado con los datos del formulario,
id="email" //Selector identificador el cual lo enlazará con el label correspondiente
**onChange={(e) => setEmail(e.target.value)}** //"prop"(propiedad) ****tributo manejador de eventos de "cambio de valor", con valor de ejecutar código de JS entre llaves, ejecutando una función flecha que recibe como argumento dicho evento ejecutado, la cual llama a ejecutar la función de actualización del estado la cual recibe como argumento, del evento ejecutado acceder al elemento que lo ejecutó y obtener su valor, siendo dicho valor el nuevo valor actual del compente
/>
</div>
<div> <!--Etiqueta contenedora de bloque-->
<button>Send data</button> <!--Etiqueta de botón, contiene texto-->
</div>
</form>
</div>
);
}
UNCONTROLLED COMPONETS:
Al contrario de los componentes controlados, la funcionalidad es ejecutada desde el DOM.
En éstos componentes lo único que se puede hacer es obtener valores e información, NO se puede modificar o controlar.
REFERENCIAS:
- Permite acceder directamente al elemento HTML mediante el DOM original.
- Permite acceder a los datos del elemento, mas no modificarlos.
- Ayuda para elementos que no pueden ser controlados directamente.
- Ayuda a saber si un elemento ya fue definido o si éste existe.
Para asociar la referecia con el elemento:
- En el elemento se accede a su propiedad *******ref={}*******, la cual la mayoría de los elementos HTML lo poseen.
- Dentro de las llaves por ser código de JS, se coloca el nombre declarado que ejecuta el hook useRef().
Para acceder a la información de dichas referencias:
- A la referencia declarada la cual es la que ejecuta el hook useRef(), se accede a su propiedad ***********current***********, la cual obtiene el elemento al que se está haciendo referencia.
- De dicha propiedad ***********current********, se accede al valor mediante ****value*******.
Hay un solo elemento que no se puede controlar y solo se puede acceder vía referencia:
- Cuando ***********************************se adjunta un archivo: Adjuntar.***********************************
- Éste elemento *NO* posee la propiedad *******value*******.
-
Para acceder al archivo adjuntado:
- Se accede a su propiedad ***********current***********, la cual obtiene el elemento al que se está haciendo referencia
- Y mediante files, se accede a la lista de archivos adjuntados, el cual es un objeto al que se pueden acceder a su contenido mediante el índice del lo valore como en un arreglo.
**import { useRef } from "react";** //Se importa la función(hook) para referenciar elementos mediante el DOM, desde, la librería de React
export default function App() { //Se exporta como valor por defecto, la declaración de función que será un componente JSX
**const inputNameRef = useRef();** //Declaración de variable con valor asignado de, llamar a ejecutar el hook para referenciar y acceder a un elemento del DOM
**const inputEmailRef = useRef();** //Declaración de variable con valor asignado de, llamar a ejecutar el hook para referenciar y acceder a un elemento del DOM
**const attachedFile = useRef();** //Declaración de variable con valor asignado de, llamar a ejecutar el hook para referenciar y acceder a un elemento del DOM
const handleSubmit = (e) => { //Declaración de constante con valor asignado de, una función flecha, convirtiédola en una función, la cual recibe como argumento la referencia del evento eejcutado, la cual ejecuta el siguiente bloque
e.preventDefault(); //A dicho evento ejecutado, se le aplica el método para prevenir su comportamiento por defecto, y asignale uno
console.log( //A la consola del navegador, se le aplica el método de imprimir sobre la misma lo siguiente
**inputNameRef.current.value,** //A dicho elemento referenciado desde el DOM, se accede al elemento, y a su valor
**inputEmailRef.current.value** //A dicho elemento referenciado desde el DOM, se accede al elemento, y a su valor
);
**console.log**(**attachedFile.current.files[0].name**); //A la consola del navegador, a la que se le aplica el método de imprimir sobre la misma, de dicho elemento referenciado desde el DOM, se accede al elemento, a la lista(objeto) del "archivos", se accede al primer elemento mediante su índice, y se accede a su propiedad de "nombre"
};
return ( //Se retorna dentro de paréntesis por ser un componente JSX
<div> //Etiqueta contenedora de bloque
<form onSubmit={handleSubmit}> //Etiqueta de formulario, posee el atributo manejador de eventos del evento de entregar los datos del formualrio, con valor dentro de llaves por ser código de JS, de llamar a dicha constante función apra ser ejecutada al momento de detectar la ejecución de dicho evento
<div> //Etiqueta contenedora de bloque
<label htmlFor="name">Name</label> //Etiqueta para etiquetar elementos de interfaz de usuario, posee el atributo "htmlFor" para enlazarla con el elemento correspondiente con valor de una cadena de texto la cual es la misma que el identificador del elemento a ser enlazado, y contiene texto
<input //Etiqueta de ingreso de datos, posee los siguientes atributos
type="text" //Atributo de "tipo" con valor, para ser de texto
name="name" //Atributo de "nombre" con valor, que es el nombre del control el cual es enviado con los datos del formulario
id="name" //Selector identificador el cual lo enlazará con el label correspondiente
**ref={inputNameRef}** //Propiedad de "referencia" para vincular el hook para acceder al elemento que posee ésta propiedad, con valor de, en código de JS dentro de llaves, dicha constante, la cual será éste elemento
/>
</div>
<div> //Etiqueta contenedora de bloque
<label htmlFor="email">Email</label> //Etiqueta para etiquetar elementos de interfaz de usuario, posee el atributo "htmlFor" para enlazarla con el elemento correspondiente con valor de una cadena de texto la cual es la misma que el identificador del elemento a ser enlazado, y contiene texto
<input //Etiqueta de ingreso de datos, posee los siguientes atributos
type="email" //Atributo de "tipo" con valor, para ser de correo electrónico
name="email" //Atributo de "nombre" con valor, que es el nombre del control el cual es enviado con los datos del formulario
id="email" //Selector identificador el cual lo enlazará con el label correspondiente
**ref={inputEmailRef}** //Propiedad de "referencia" para vincular el hook para acceder al elemento que posee ésta propiedad, con valor de, en código de JS dentro de llaves, dicha constante, la cual será éste elemento
/>
</div>
<div> //Etiqueta contenedora de bloque
<label htmlFor="file">Adjuntar</label> //Etiqueta para etiquetar elementos de interfaz de usuario, posee el atributo "htmlFor" para enlazarla con el elemento correspondiente con valor de una cadena de texto la cual es la misma que el identificador del elemento a ser enlazado, y contiene texto
<input //Etiqueta de ingreso de datos, posee los siguientes atributos
type="file" //Atributo de "tipo" con valor, para ser de carga de archivos
name="file" //Atributo de "nombre" con valor, que es el nombre del control el cual es enviado con los datos del formulario
id="file" //Selector identificador el cual lo enlazará con el label correspondiente
**ref={attachedFile}** //Propiedad de "referencia" para vincular el hook para acceder al elemento que posee ésta propiedad, con valor de, en código de JS dentro de llaves, dicha constante, la cual será éste elemento
/>
</div>
<div> //Etiqueta contenedora de bloque
<button>Send data</button> <!--Etiqueta de botón, contiene texto-->
</div>
</form>
</div>
);
}
REFERENCIAS:
Las referencias o mejor conocidas dentro de React como Refs, nos permiten acceder a propiedades del elemento dentro del DOM directamente.
-
No usar Ref:
- Para simular comportamientos de componentes controlados (anti-patterns).
-
Usar Ref:
- Solo usamos refs cuando necesitemos implicitamente llamar a un comportamiento que React no nos permita controlar.
- Integrar con librerías de terceros.
- Gestionar focus, text selection, etc.
- Detectar si el elemento existe o no.
- Cuando haya necesidad de acceder a un elemento del DOM.
-
Para acceder a las referencias:
- se utiliza el hook *****useRef()****, la cual debe ser asignada a una variable, y dicha variable debe ser enlazada a un elemento de etiqueta HTML JSX mediante la propiedad de "ref={}*":
**import { useEffect, useRef } from "react";** //Se importan la funciónes(hooks) para referenciar elementos mediante el DOM, desde, la librería de React export default function DemoFocus() { //Se exporta como valor por defecto, la declaración de fucnión que será un componente JSX, la cual eecuta el siguiente bloque **const inputRef = useRef();** //Declaración de variable con valor asignado de, llamar a ejecutar el hook para referenciar y acceder a un elemento del DOM useEffect(() => { //Se llama a ejecutar la función para manejar los efectos secundarios del componente, la cual recibe como primer argumento una función flecha, la cual ejecuta el siguiente bloque console.log("Mounted"); //A la consola del navegador, se le aplica el método de imprimir sobre la misma, la cadena de texto envida como argumento console.log(**inputRef**); //A la consola del navegador, se le aplica el método de imprimir sobre la misma, el valor de dicha referencia, el cual es el elemento del DOM, que en su propiedad "ref" tenga asignado dicha referencia if (**inputRef.current**) { //Condicional que valida que, si, de dicho elemento referenciado desde el DOM, se accede al elemento, para validar si existe al obtener valor "true", ejecutando el siguiente bloque si se cumple dicha condición **inputRef.current.focus()**; //A dicho elemento referenciado desde el DOM, se accede al elemento, y se aplica el método para hacer focus sobre el mismo } }, []); //Como segundo argumento, recibe un arreglo vacío, así ejecutando el efecto la primera y última vez que se renderice el componente return ( //Se retorna dentro de paréntesis por ser un componente JSX <input type="text" **ref={inputRef}**/> //Etiqueta de ingreso de datos, posee el atributo de "tipo" con valor para ser de texto, y la propiedad de "referencia" para vincular el hook para acceder al elemento que posee ésta propiedad, con valor de, en código de JS dentro de llaves, dicha constante la cual será éste elemento ); } export function DemoFocusDos() { //Se exporta ladeclaraciónde función que será un compente, la cual ejecuta el siguiente bloque **const inputRef = useRef();** //Declaración de variable con valor asignado de, llamar a ejecutar el hook para referenciar y acceder a un elemento del DOM const handleClick = () => { //Declaración de constante con valor asignado de, una función flecha, convirtiédola en una función, la cual ejecuta el siguiente bloque **inputRef.current.focus()**; //A dicho elemento referenciado desde el DOM, se accede al elemento, y se aplica el método para hacer focus sobre el mismo console.log(**inputRef.current.value**); //LLamado a la consola del navegador, a la que se le aplica el método para imprimir sobre la misma, a dicho elemento referenciado desde el DOM, se accede al elemento, y a su valor } return ( //Se retorna dentro de paréntesis por ser un componente JSX <> //Fragmento de React para contener el componente sin ser renderizado dentro de otro elemento <input type="text" **ref={inputRef}**/> //Etiqueta de ingreso de datos, posee el atributo de "tipo" con valor para ser de texto, y la propiedad de "referencia" para vincular el hook para acceder al elemento que posee ésta propiedad, con valor de, en código de JS dentro de llaves, dicha constante la cual será éste elemento <button onClick={handleClick}>Focus</button> //Etiqueta de botón, posee la propiedad manejadora de eventos para el evento de click sobre el mismo, con valor dentro de llaves por ser código de JS, de llamar a dicha constante función para ser ejecutada cuado se ejecute dicho evento, y la cual contiene texto </> ); }
forwardRef():
Esta función es necesaria para poder crear un componente funcional que soporte el uso de referencias (refs).
Esta técnica la vamos a utilizar cuando nos veamos en la necesidad de aislar funcionalidad.
Esto significa que nos permitirá no perder la referencia del elemento aunque este en otro componente.
Es una forma en la cual no se pierde la referencia que se tiene desde dentro para utilizarla desde fuera, *****************solamente como referencia del elemento que se está seleccionado*****************, no del componente.
En resumen, ayuda a no perder la referencia del elemento que esté en otro componente y así mismo poderlo reutilizar en alguna otra parte del código.
Para implementarlo:
- Se debe importar la función forwardRef desde la librería de React. Dicha función ayuda a contener un componente y le agrega propiedades para poder tener acceso a esa información.
- Al llamar a ejecutar la función forwardRef(), se le envía un componente como argumento, así se le indica que se le hace una devolución de la referencia hacia el componente padre que lo esté llamando.
- Al componente que será enviado como argumento a la función forwardRef(), a demás de poseer el parámetro para recibir las “*****props**”, posee el parámetro **ref***** para recibir una referencia la cual será la referencia que se obtiene desde la función forwardRef() la cual es la que se va a asociar a la referencia que se está aplicando desde afuera.
Para obtener la referencia de un elemento dentro de un componente:
- Al llamar a ejecutar el componente como etiqueta de HTML JSX, se le coloca la propiedad *********************ref={}********************* a la cual se le asigna como valor dentro de llaves por ser código de JS, la variable/constante que utiliza el hook *****useRef()*****.
- Así se le agrega la propiedad *********ref={}********* al componente, la cual hará referencia al elemento contenido dentro del componente que posea la propiedad *********ref={}********* la cual tiene el valor que se envíe al parámetro ***ref*** del componente que posee dicho elemento contenido.
//InputForward.jsx
**import { forwardRef } from "react";** //Se importa la función "forwardRef", desde, la librería de React, para poder crear un componente funcional que soporte el uso de referencias (refs)
**function InputForward(props, ref) {** //Declaración de función, la cual posee el parámetro para recibir el objeto de propiedades(props), y el parámetro para recibir la referencia que se utilizará para acceder al elemento interno del componente, en este caso, el input
return ( //Se retorna dentro de paréntesis por ser un componente JSX
<> //Fragmento de React para contener el componente sin ser renderizado dentro de otro elemento
<label htmlFor="input">{props.label}</label> //Etiqueta para etiquetar elementos de interfaz de usuario, posee el atributo "htmlFor" para enlazarla con el elemento correspondiente con valor de una cadena de texto la cual es la misma que el identificador del elemento a ser enlazado, y contiene dentro de llaves por ser código de JS, del objeto de "props" enviado al componente, acceder a la propiedad label el cual será un elemento label
**<input type="text" ref={ref} id="input"/>** //Etiqueta de entrada de datos, la cual posee la propiedad de "tipo" con valor para ser de texto, y la propiedad de "referencia" con valor dentro de llaves por ser código de JS, de la referencia pasada al parámetro del componente, esto permitirá que la referencia se enlace al elemento input interno del componente, y un selector identificaor para enlazarlo con su respectivo label
</>
);
}
**export default forwardRef(InputForward);** //Se exporta como valor por defecto, llamar a ejecutar la función "forwardRef", la cual recibe como argumento, el componente InputForward, esto permite que el componente pueda ser utilizado por un componente padre que necesita acceder al elemento input interno utilizando una referencia
//App.jsx
import { useEffect, **useRef** } from "react"; //Se importan los hooks useEffect y useRef de la librería de React, el hook useRef se utilizará para crear una referencia que apuntará al input interno del componente "ForwardRef"
**import ForwardRef from "./components/inputForward";** //Se importa el componente "**ForwardRef**", desde, su ruta de archivo
export default function App() { //Se exporta como valor por defecto, la declaración de función que será un componente, y que ejecuta el siguiente bloque
**const inputRef = useRef();** //Declaración de constante con valor asignado de, llamar a ejecutar el hook para referenciar y acceder a un elemento del DOM, el cual es el input interno del componente "ForwardRef"
useEffect(() => { //Se llama a ejecutar la función para manejar los efectos secundarios del componente, la cual recibe como primer argumento una función flecha, la cual ejecuta el siguiente bloque
**console.log("ref input", inputRef);** //LLamado a la consola del navegador, a la que se le aplica el método para imprimir sobre la misma, la cadena de texto, y el valor de dicha constante, el cual es el elemento contenido dentro del componente **ForwardRef** al que se le hace referencia
handleFocusForward(); //Se llama a ejecutar dicha constante función
}, []) //Como segundo argumento, recibe un arreglo vacío, así ejecutando el efecto la primera y última vez que se renderice el componente
const handleFocusForward = () => { //Declaración de función con valor asignado de, una función de flecha, así convirtiéndola en una función, y que ejecuta el siguiente bloque
**inputRef.current.focus();** //De dicha referencia que es el elementos, se accede al elemento mismo, y se le aplica el método para hacer "enfoque" sobre el mismo, para eso se utilizó la referencia
}
return ( //Se retorna dentro de paréntesis por ser un componente JSX
<div> //Etiqueta contenedora de bloque
**<ForwardRef ref={inputRef} label="Nombre"/>** //Se llama a ejecutar dicho componete como etiqieta HTML JSX, la cual posee la propiedad de "referencia" la cual fue dada mediante la función **forwardRef** y que tiene valor asignado de, vincular la referencia inputRef para acceder al elemento contenido dentro de éste componente, al que se quiere acceder y que también tiene la propiedad ref, siendo así que la constante **inputRef** es la referencia del elemento input contenido dentro del componente, y también se le pasa una propiedad "label" con el valor "Nombre", así se vincula con la referencia "inputRef" para que el componente padre ("App") pueda acceder a él.
</div>
);
}
useImperativeHandle():
Al igual que el ref, este hook nos permitirá de igual forma pasar la referencia de un elemento para poder utilizarla dentro de un componente, a diferencia de utilizar directamente el ref que se asoció a un elemento, la referencia es asociada a useImperativeHandle() para indicar que nosotros vamos a personalizar los datos o atributos que se retornan a esta referencia.
Sin embargo, además nos permitirá personalizar lo que se regresa en la referencia, ya sea para devolver algún dato/función que nos permita cambiar su comportamiento.
Para implementarlo:
- Se debe importar la función useImperativeHandle desde la librería de React.
-
Al llamar a ejecutar la función forwardRef(), posee:
- Como primer parámetro para recibir el argumento que será una referencia de un elemento la cual es la que va a llegar desde donde se quiere obtener.
- Como segundo parámetro, una función flecha callback la cual va a retornar lo que se requiera.
//Slider.jsx **import { forwardRef, useImperativeHandle } from "react"**; //Se importan las funciones "forwardRef" para pasar "refs" de un componente secundario al componente padre, y "useImperativeHandle" que permite exponer funciones específicas del componente hijo a través del "ref" del componente padre import { useKeenSlider } from "keen-slider/react"; //Se importa el hook "useKeenSlider" desde, librería "keen-slider" para react, que permite inicializar y utilizar el slider import 'keen-slider/keen-slider.min.css'; //Se importa un archivo de CSS, desde su ruta const Slider = (props, ref) => { //Declaración de constante que será un compoente JSX, con valor asignado de una función flecha, la cual posee como primer parámetro para recibir como argumento el objeto "props", y como segundo parámetro para recibir como argumento una "referencia" para poder ser usada en un componente padre **const [sliderRef, intanceRef] = useKeenSlider()**; //Declaración de constante con sintaxis de destructuración de arreglos, siendo el primer valor una referencia que debe adjuntarse al contenedor del slider (div.keen-slider en este caso) para que funcione correctamente, y el segundo valor una referencia al objeto de instancia del slider que representa el objeto de instancia del slider que contiene varios métodos y propiedades útiles para controlar y gestionar el slider los cuales son métodos como "next" y "prev" para controlar la navegación del slider, y tiene valor asignado de, llamar a ejecutar dicho hook para acceder a dichos valores destructurados **useImperativeHandle(ref, () => {** //Se llama a ejecutar el hook que permite exponer funciones específicas del componente hijo a través del "ref" del componente padre, la cual recibe como primer argumento es la "ref" que se pasa al componente hijo (en este caso, al componente Slider), y como segundo argumento reibe una función de flecha que debe devolver un objeto para personalizar lo que se retornará a dicha referencia, y que ejecuta el siguiente bloque **return {** //Se retorna un objeto con las siguientes propiedades **next: intanceRef.current.next,** //Propiedad del objeto, con valor de, de dicho objeto que posee propiedades para controlar y gestionar el slider, con "current" se accede al dicho objeto, para poder acceder a su método para avanzar al siguiente slide en el slider **prev: intanceRef.current.prev** //Propiedad del objeto, con valor de, de dicho objeto que posee propiedades para controlar y gestionar el slider, con "current" se accede al dicho objeto, para poder acceder a su método para retroceder al anterior slide en el slider **} })**; return ( //Se retorna dentro de paréntesis por ser un componente JSX <> //Fragmento de React para contener el componente sin ser renderizado dentro de otro elemento **<div className="keen-slider" ref={sliderRef}**> //Etiqueta contenedora de bloque, la cual posee un selector de clase con valor de "keen-slider", y posee el atributo de referencia que se obtuvo a partir del hook "useKeenSlider" para asegurar que el slider pueda funcionar correctamente al vincular la referencia con el contenedor del slider. <div className="keen-slider__slide">1</div> //Etiqueta contenedora de bloque, la cual posee un selector de clase con valor de "keen-slider__slide" y contiene texto <div className="keen-slider__slide">2</div> //Etiqueta contenedora de bloque, la cual posee un selector de clase con valor de "keen-slider__slide" y contiene texto <div className="keen-slider__slide">3</div> //Etiqueta contenedora de bloque, la cual posee un selector de clase con valor de "keen-slider__slide" y contiene texto </div> </> ); } **export default forwardRef(Slider)**; //Se exporta como valor por defecto, el componente "Slider" utilizando "forwardRef", lo que permite que el componente padre pueda acceder a las funciones next y prev proporcionadas por el ref de este componente.
```jsx
//App.jsx
**import { useEffect, useRef } from "react"**; //Se importan los hooks useEffect y useRef de la librería de React, el hook "useEffect" maneja los efectos secundarios de un componente, y le hook "useRef" se utilizará para crear una referencia que apuntará al input interno del componente "ForwardRef"
**import Slider from "./components/Slider"**; //Se importa como valor por defecto, dicho componente, desde, su ruta
export default function App() { //Se exporta como valor por defecto, la declaración de función que será un componente, y que ejecuta el siguiente bloque
**const sliderRef = useRef()**; //Declaración de constante con valor asignado de, llamar a ejecutar el hook para referenciar y acceder a un elemento del DOM, el cual será el que en su atributo "ref" tenga ésta refencia asignada, para acceder a la instancia del componente "Slider"
useEffect(() => { //Se llama a ejecutar la función para manejar los efectos secundarios del componente, la cual recibe como primer argumento una función flecha, la cual ejecuta el siguiente bloque
**console.log("ref input", sliderRef)**; //A la consola del navegador, se le aplica el método para imprimir sobre la misma, dicha cadena de texto, y el valor de dicha referencia, el cual es el objeto con métodos para controlar y gestionar el slider
}, []) //Como segundo argumento, recibe un arreglo vacío, así ejecutando el efecto la primera y última vez que se renderice el componente
return ( //Se retorna dentro de paréntesis por ser un componente JSX
<div> //Etiqueta contenedora de bloque
**<button onClick={() => sliderRef.current.prev()}>Prev</button>** //Etiqueta de botón, la cual posee la propiedad manejadora de eventos del evento e click sobre éste elemento, con valor asignado dentro de llaves por ser código de JS, una función de flecha callback la cual ejecuta, de dicha referencia que es el objeto con métodos para controlar y gestionar el slider, acceder a dicho objeto, y llamar a ejecutar su propiedad método "prev()", y contiene texto
**<button onClick={() => sliderRef.current.next()}>Next</button>** //Etiqueta de botón, la cual posee la propiedad manejadora de eventos del evento e click sobre éste elemento, con valor asignado dentro de llaves por ser código de JS, una función de flecha callback la cual ejecuta, de dicha referencia que es el objeto con métodos para controlar y gestionar el slider, acceder a dicho objeto, y llamar a ejecutar su propiedad método "next()", y contiene texto
**<Slider ref={sliderRef}/>** //Se llama a ejecutar dicho componente para como etiquta HTML para ser renderizado, y recibe la "prop" de "referencia" con valor asignado dentro de llaves por ser código de JS, dicha referencia "sliderRef" lo que permite que el componente App acceda y controle la instancia del slider a través de la referencia, esto hace que los botones "Prev" y "Next" controlen el desplazamiento del slider
</div>
);
}
```
LISTAS Y LLAVES:
Las listas nos ayudan a renderizar un set de elementos con diferentes tipos de información.
KEYS:
Son una forma de identificar un elemento de otro en las listas que son repetitivas.
- Las llaves “*****keys*****” deben ser identificadores únicos para no causar conflictos entre elementos.
import PropTypes from "prop-types"; //Se importa la librería PropTypes, desde, "prop-types" que se utiliza para declarar y validar los tipos de las propiedades que se pasan a los componentes
import { useState } from "react"; //Se importa la función hook "useState", desde la librería de react, para agregar el estado a los componentes
**const data = [** //Declaración de constante con valor asignado de, un arreglo, el cual contiene los siguientes objetos
**{** //Objeto, posee las siguientes propiedades
**id: 1,** //Propiedad del objeto, con valor numérico 1
**name: 'Rodrigo',** //Propiedad del objeto, con valor de una cadena de texto
**question: '¿What is React?'** //Propiedad del objeto, con valor de una cadena de texto
**},
{
id: 2,** //Propiedad del objeto, con valor numérico 1
**name: 'Angelica',** //Propiedad del objeto, con valor de una cadena de texto
**question: '¿What is design?'** //Propiedad del objeto, con valor de una cadena de texto
**}
];**
const Question = (**{id, name, question}**) => { //Declaración de constante que será un componente, con valor de una función de flecha, la cual recibe como argumento la destructuración de un objeto para acceder individualmente a cada una de las propiedades evitando mutarlas las cuales serán "propiedades", conviertiendo la constante en una función, la cual ejecuta el siguiente bloqu
return ( //Se retorna dentro de paréntesis por ser un componente JSX
<> //Fragmento de React para contener el componente sin ser renderizado dentro de otro elemento
<h2>UserId: **{id}**</h2> //Etiqueta de subtítulo, la cual contiene texto, y dentro de llaves por ser código de JS, el valor de dicha propiedad "id" destructurada del objeto "prop" envíado a la función componente "Question"
<span>**{name}**</span> //Etiqueta contenedora en línea, la cual contiene dentro de llaves por ser código de JS, el valor de dicha propiedad "name" destructurada del objeto "prop" envíado a la función componente "Question"
<p>**{question}**</p> //Etiqueta de párrafo, la cual contiene dentro de llaves por ser código de JS, el valor de dicha propiedad "question" destructurada del objeto "prop" envíado a la función componente "Question"
</>
)
}
export default function List() { //Se exporta como valor por defecto, la declaración de función que será un componente, y que ejecuta el siguiente bloque
****const [**question**, setQuestion] = useState**(data);** //Declaración de constante la cual será el estado del componente, en la cual se utiliza la sintaxis de destructuración de arreglos, siendo el primer valor, el valor actual del estado el cual empieza siendo el valor por defecto enviado a "useState", y como segundo valor la función que actualizará el estado, dicha constante tiene valor asignado de, llamar a ejecutar la función importada para el estado del componente, la cual recibe como argumento para el valor por defecto del componente, el valor de dicho arreglo para poder acceder a los objetos y sus propiedades
return ( //Se retorna dentro de paréntesis por ser un componente JSX
<> //Fragmento de React para contener el componente sin ser renderizado dentro de otro elemento
<ul> //Etiqueta de lista desordenada, la cual contiene dentro de llaves por ser código de JS, lo siguiente
**{question.map((question) =>** //Sobre el estado actual del componente, el cual es el arreglo "data", se aplica el método de crear un nuevo arreglo aplicando una función por cada elemento que es un objeto dentro del arreglo, el cual recibe como argumento una función de flecha que por cada elemento "question" ejecuta el sigueinte bloque
**<Question {...question} key={question.id} />** //Se llama a ejecutar dicho componente como etiqueta HTML para ser renderizado, el cual recibe como "props" un objeto utilizando el "spread operator" el cual es el objeto dentro del arreglo "data" así recibe las propiedades "id", "name", y "question" correspondientes a cada objeto dentro del arreglo "data", también posee el atributo "key" para dar una identificación única a cada elemento en la lista, con valor asignado dentro de llaves por ser código de JS, del objeto dentro del arreglo "data", acceder a su propiedad "id" siendo asignado su valor
**)}**
</ul>
</>
);
}
Question.propTypes = { //Al componente "Question", se accede a su propiedad "propTypes" para especificar los tipos de datos esperados para las props, a la cual se le asigna como valor, un objeto con las siguientes propiedades
id: PropTypes.number, //Se establece que, la propiedad "id" debe, desde la librería "PropTypes", ser un valor numérico
name: PropTypes.string, //Se establece que, la propiedad "name" debe, desde la librería "PropTypes", ser un valor de cadena de texto
question: PropTypes.string, //Se establece que, la propiedad "question" debe, desde la librería "PropTypes", ser un valor de cadena de texto
}
EJEMPLO:
import { useState } from "react"; //Se importa la función hook "useState", desde la librería de react, para agregar el estado a los componentes
import PropTypes from "prop-types"; //Se importa la librería PropTypes, desde, "prop-types" que se utiliza para declarar y validar los tipos de las propiedades que se pasan a los componentes
export const Question = () => { //Se importa como valor por defecto, la declaración de constante que será un componente, con valor asignado de, una funicón de flecha que ejecuta el siguiente bloque, así la constante se convierte en una función
const [name, setName] = useState(""); //Declaración de constante la cual será un estado del componente, en la cual se utiliza la sintaxis de destructuración de arreglos, siendo el primer valor, el valor actual del estado el cual empieza siendo el valor por defecto enviado a "useState", y como segundo valor la función que actualizará el estado, dicha constante tiene valor asignado de, llamar a ejecutar la función importada para el estado del componente, la cual recibe como argumento para el valor por defecto del componente, el valor de una cadena de texto vacía
const [question, setQuestion] = useState(""); //Declaración de constante la cual será un estado del componente, en la cual se utiliza la sintaxis de destructuración de arreglos, siendo el primer valor, el valor actual del estado el cual empieza siendo el valor por defecto enviado a "useState", y como segundo valor la función que actualizará el estado, dicha constante tiene valor asignado de, llamar a ejecutar la función importada para el estado del componente, la cual recibe como argumento para el valor por defecto del componente, el valor de una cadena de texto vacía
const [questionsList, setQuestionsList] = useState([]); //Declaración de constante la cual será un estado del componente, en la cual se utiliza la sintaxis de destructuración de arreglos, siendo el primer valor, el valor actual del estado el cual empieza siendo el valor por defecto enviado a "useState", y como segundo valor la función que actualizará el estado, dicha constante tiene valor asignado de, llamar a ejecutar la función importada para el estado del componente, la cual recibe como argumento para el valor por defecto del componente, un arreglo vacío
const handleSubmit = (e) => { //Declaración de constante, con valor asignado de una función de flecha la cual recibe como argumento un evento ejecutado, la cual ejecuta el siguiente bloque, así cual controlará el comportamiento al enviar los datos del formulario
e.preventDefault(); //A dicho evento ejecutado, se le aplica el método para prevenir su comportamiento por defecto, para controlar su comportamiento
setQuestionsList([ { name, question }, ...questionsList]); //Se llama a ejecutar la función de actualización del estado "questionsList" la cual es un arreglo, la cual recibe como argumento, un nuevo arreglo, el cual es una copia del arreglo "questionsList", el cual recibe un objeto que representa la "pregunta a ser renderizada" el cual posee dos propiedades cuyos valores provienen de aambos estados del componente, así cada nueva pregunta será colocada al inicio de la lista para ser renderizada al incio del componente, y como segundo elemento dentro del nuevo arreglo, se utiliza operador de propagación que toma cada elemento del arreglo "questionsList" y los incluye en el nuevo array. Esto asegura que no estamos modificando directamente el array questionsList original, así se mantendrán renderizadas las preguntas anteriores y las nuevas preguntas
setName(""); //Se llama a ejecutar la función de actualización del estado "name", la cual recibe como argumento, una cadena vacía, pará así actualizar el estado, que esta cadena vacía sea en nuevo valor actual del estado, para que así se vacie el campo del input que controla este estado
setQuestion(""); //Se llama a ejecutar la función de actualización del estado "question", la cual recibe como argumento, una cadena vacía, pará así actualizar el estado, que esta cadena vacía sea en nuevo valor actual del estado, para que así se vacie el campo del input que controla este estado
};
const handleNameChange = (e) => { //Declaración de constante, con valor asignado de una función de flecha la cual recibe como argumento un evento ejecutado, la cual ejecuta el siguiente bloque, así cual controlará el comportamiento al detectar un cambio de valor en el input "name"
setName(e.target.value); //Se llama a ejecutar la función de actualización del estado "name", la cual recibe como argumento, del evento ejecutado, acceder al elemento que lo ejecutó, y acceder a su valor, para que así cada vez que se actualice el valor del input que ejecuta el evento "onChange", ese valor sea el nuevo valor actual del estado
};
const handleQuestionChange = (e) => { //Declaración de constante, con valor asignado de una función de flecha la cual recibe como argumento un evento ejecutado, la cual ejecuta el siguiente bloque, así cual controlará el comportamiento al detectar un cambio de valor en el input "question"
setQuestion(e.target.value); //Se llama a ejecutar la función de actualización del estado "question", la cual recibe como argumento, del evento ejecutado, acceder al elemento que lo ejecutó, y acceder a su valor, para que así cada vez que se actualice el valor del input que ejecuta el evento "onChange", ese valor sea el nuevo valor actual del estado
};
return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis
<> //Fragmento de React para contener el componente sin ser renderizado dentro de otro elemento
<form onSubmit={handleSubmit}> //Etiqueta de formulario, la cual posee el atributo manejador de eventos del evento de "entrega" de datos del formulario, con valor asignado dentro de llaves por ser código de JS, de ejecutar dicha función para controlar el comportamiento de dicho evento
<div> //Etiqueta contenedora de bloque
<input //Etiqueta de ingreso de datos, la cual posee las siguiente propiedades
type="text" //Propiedad de tipo, con valor para ser de "texto"
id="name" //Selector identificador, con valor de cadena de texto, para enlazarlo con su respectivo label
value={name} //Propiedad de valor, con valor dentro de llaves por ser código de JS, de el valor actual de su respectivo estado
onChange={handleNameChange} //Propiedad manejadora de eventos del evento de "cambio de valor" del input, con valor asignado dentro de llaves por ser código de JS, de ejecutar dicha función para controlar el comportamiento de dicho evento, cada vez que cambie el valor de éste input
required //Propiedad de "requerido" para que el vlaor de éste input sea obligatorio
/>
<label htmlFor="name">Name</label> //Etiqueta para etiquetar elementos de interfaz de usuario, posee el atributo "htmlFor" para enlazarla con el elemento correspondiente con valor de una cadena de texto la cual es la misma que el identificador del elemento a ser enlazado, y contiene texto
</div>
<div> //Etiqueta contenedora de bloque
<label htmlFor="question">Question</label> //Etiqueta para etiquetar elementos de interfaz de usuario, posee el atributo "htmlFor" para enlazarla con el elemento correspondiente con valor de una cadena de texto la cual es la misma que el identificador del elemento a ser enlazado, y contiene texto
<br /> //Etiqueta de salto de línea
<input //Etiqueta de ingreso de datos, la cual posee las siguiente propiedades
type="text" //Propiedad de tipo, con valor para ser de "texto"
id="question" //Selector identificador, con valor de cadena de texto, para enlazarlo con su respectivo label
value={question} //Propiedad de valor, con valor dentro de llaves por ser código de JS, de el valor actual de su respectivo estado
onChange={handleQuestionChange} //Propiedad manejadora de eventos del evento de "cambio de valor" del input, con valor asignado dentro de llaves por ser código de JS, de ejecutar dicha función para controlar el comportamiento de dicho evento, cada vez que cambie el valor de éste input
required //Propiedad de "requerido" para que el vlaor de éste input sea obligatorio
/>
</div>
<div> //Etiqueta contenedora de bloque
<button type="submit">Post</button> //Etiqueta de botón, posee la propiedad de "tipo" con valor para ser de "entregar" los valores del formulario, y contiene texto
</div>
</form>
<div> //Etiqueta contenedora de bloque
{questionsList.map((q, index) => ( //Dentro de llaves por ser código de JS, al estado actual del estado "questionsList" el cual es una lista, aplicar el método para crear un nuevo arreglo aplicando una fución a cada uno de los elementos dentro del arreglo, el cual reicibe como primer arguento, la referencia a cada uno de los elementos dentro de dicho arreglo, y como segundo argumento, el indice que será de cada uno de los elementos, y por cada elemento dentro de dicho arreglo, se ejecuta el siguiente bloque
<ListQuestions //Se llama a renderizar dicho componente, el cual posee las siguientes "props"(propiedades)
key={index} //Propiedad que se requiere cuando se renderiza una lista de componentes en React, ayuda a React a identificar de manera única cada elemento en la lista y mejora el rendimiento al realizar actualizaciones en la interfaz de usuario, con valor asignado dentro de llaves por ser código de JS, de el valor del índice del elemento, para que éste seá único
name={q.name} //Propiedad "prop" necesaria para el componente, con valor asignado dentro de llaves por ser código de JS, del elemento dentro de arreglo, acceder a su propiedad "name" para obtener su valor
question={q.question} //Propiedad "prop" necesaria para el componente, con valor asignado dentro de llaves por ser código de JS, del elemento dentro de arreglo, acceder a su propiedad "question" para obtener su valor
/>
))}
</div>
</>
);
};
function ListQuestions(props) { //Declaración de función que será un componente, el cual posee un parámetro para recibir sus "props", y que ejecuta el siguiente bloque
return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis
<div> //Etiqueta contenedora de bloque
<h2>{props.name}</h2> //Etiqueta de subtítulo, la cual contiene dentro de llaves por ser código de JS, del objeto de "propiedades", acceder a su propiedad de "name" para obtener su valor
<p>{props.question}</p> //Etiqueta de párrafo, la cual contiene dentro de llaves por ser código de JS, del objeto de "propiedades", acceder a su propiedad de "question" para obtener su valor
</div>
);
}
ListQuestions.propTypes = { //Al componente "ListQuestions", se accede a su propiedad "propTypes" para especificar los tipos de datos esperados para las props, a la cual se le asigna como valor, un objeto con las siguientes propiedades
name: PropTypes.string, //Se establece que, la propiedad "name" debe, desde la librería "PropTypes", ser un valor de cadena de texto
question: PropTypes.string, //Se establece que, la propiedad "question" debe, desde la librería "PropTypes", ser un valor de cadena de texto
};
Top comments (0)