MA: Entorno
+Tanto trabajando con React como con JavaScript puede ser útil leer propiedades del navegador, así como almacenar información en los dispositivos locales.
+ + + +diff --git a/_quarto.yml b/_quarto.yml index fa4635b..18580f8 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -75,9 +75,18 @@ website: contents: - pages/Bloque3/Intermedio.qmd - pages/Bloque3/MARef.qmd + + - section: "Semana 10" + contents: + - pages/Bloque3/ReactIV.qmd +<<<<<<< HEAD + - pages/Bloque3/t10.qmd +======= + - text: "Próximamente..." +>>>>>>> 8e10774 (feat: explicacion semana 10 (#4)) - section: "Bloque IV Comunicación" diff --git a/docs/about.pdf b/docs/about.pdf index fe9334c..5aa0478 100644 Binary files a/docs/about.pdf and b/docs/about.pdf differ diff --git a/docs/index.html b/docs/index.html index ad6869c..84f3bda 100644 --- a/docs/index.html +++ b/docs/index.html @@ -506,8 +506,39 @@ +
useRefTanto trabajando con React como con JavaScript puede ser útil leer propiedades del navegador, así como almacenar información en los dispositivos locales.
+ + + +Ecosistema npm, React Router, useContext
Contenido
+useContextHasta ahora hemos trabajado únicamente con React y JavaScript.
+Sin embargo, en el desarrollo real de aplicaciones es muy común utilizar librerías externas, para ello podemos recurrir Node.JS.
React está diseñado para funcionar dentro de un ecosistema de paquetes.
+Ejemplos habituales:
+npm (Node Package Manager) es el sistema que permite instalar y gestionar librerías de JavaScript. Como su nombre indica, está desarrollado por Node.JS
+Cada proyecto tiene un archivo:
+package.json
+En este archivo se registran las dependencias del proyecto.
+Ejemplo:
+{
+ "dependencies": {
+ "react": "^18.0.0",
+ "react-router-dom": "^6.0.0"
+ }
+}Las librerías se instalan desde la terminal.
+npm install react-router-domEsto hace tres cosas:
+node_modules (capreta donde se guardan las librerías externas)package.jsonEn una aplicación web tradicional cada enlace carga una página nueva.
+En React normalmente trabajamos con Single Page Applications (SPA).
+En una SPA:
+Para gestionar esto utilizamos React Router.
+Realmente es la misma página, solo que el usuario lo percibe como distintas páginas
+El usuario percibirá que el sitio web está divido en diferentes subpáginas
+/pokemonspokemons/pikachuLos elementos fundamentales son:
+BrowserRouterRoutesRouteLinkEjemplo básico:
+Elementos del código
+BrowserRouterRoutesRoutepath/ corresponde a la página principal.elementpath.<Home />/.<PokemonList />/pokemons.Podemos crear rutas dinámicas.
+Ejemplo:
+/pokemon/25
+/pokemon/7
+Definición de la ruta:
+<Route path="/pokemon/:id" element={<PokemonDetail />} />Para acceder al parámetro utilizamos el hook useParams de React Router.
import { useParams } from "react-router-dom";
+
+function PokemonDetail() {
+
+ const { id } = useParams();
+
+ return <p>Pokemon {id}</p>;
+
+}Este parámetro puede utilizarse para realizar peticiones a una API.
+En aplicaciones grandes aparece un problema frecuente.
+Muchos componentes necesitan acceder a la misma información.
+Por ejemplo:
+Si pasamos la información mediante props, los datos deben atravesar muchos componentes.
+Representación conceptual:
+App
+ └ Layout
+ └ Page
+ └ Component
+Si todos necesitan user, debemos pasar la prop continuamente.
Este problema se conoce como prop drilling.
+React proporciona una solución llamada Context.
+Context permite compartir información entre múltiples componentes sin pasar props manualmente.
+El proceso tiene tres pasos:
+import { createContext } from "react";
+
+const UserContext = createContext();Esto crea un contenedor que puede almacenar información compartida.
+El Provider permite que los componentes hijos accedan al contexto.
<UserContext.Provider value={user}>
+
+ <App />
+
+</UserContext.Provider>Todos los componentes dentro del Provider pueden acceder al valor.
Para acceder al contexto utilizamos el hook useContext.
import { useContext } from "react";
+
+const user = useContext(UserContext);El componente obtiene directamente el valor almacenado en el contexto.
+import { createContext, useContext } from "react";
+
+const UserContext = createContext();
+
+function App() {
+
+ const user = { name: "Javier" };
+
+ return (
+
+ <UserContext.Provider value={user}>
+
+ <Profile />
+
+ </UserContext.Provider>
+
+ );
+}
+
+function Profile() {
+
+ const user = useContext(UserContext);
+
+ return <h1>{user.name}</h1>;
+
+}Desarrollar una aplicación React que permita al usuario realizar un quiz de cultura general utilizando preguntas obtenidas desde una API pública.
+https://astonishing-douhua-44213e.netlify.app/
+La aplicación debe mostrar preguntas, permitir seleccionar respuestas y calcular la puntuación final.
+Utilizaremos la siguiente API:
+https://the-trivia-api.com/api/questions?limit=10
+Ejemplo de respuesta:
+{
+ "question": "What is the capital of France?",
+ "correctAnswer": "Paris",
+ "incorrectAnswers": ["Madrid", "Rome", "Berlin"]
+}La aplicación debe utilizar:
+useStateuseEffectfetchNo se deben utilizar librerías externas.
+La aplicación debe estar organizada al menos con esta estructura:
+src
+ ├─ components
+ │ ├─ Question.jsx
+ │ └─ Answers.jsx
+ ├─ pages
+ │ └─ Quiz.jsx
+ ├─ App.jsx
+ └─ main.jsx
+Cuando la aplicación se inicia debe obtener 10 preguntas desde la API.
+Para ello se debe usar:
+fetchuseEffectMientras se cargan los datos se debe mostrar:
+Loading...
+La aplicación debe mostrar:
+Ejemplo:
+Question 3
+What is the capital of France?
+Cada pregunta tiene:
+Se deben mostrar las 4 respuestas como botones.
+Ejemplo:
+Paris
+Rome
+Madrid
+Berlin
+Cuando el usuario hace clic en una respuesta:
+Debe existir un botón:
+Next
+Este botón:
+Cuando el usuario responde una pregunta:
+Al terminar el quiz debe mostrarse:
+Quiz finished!
+Your score: X / 10
+useState)La aplicación debe utilizar varios estados. Por ejemplo:
+questions
+currentQuestion
+selectedAnswer
+score
+showResult
+
+
+El objetivo de esta tarea es aplicar los conceptos básicos de HTML, CSS y JavaScript (DOM) para crear una página web interactiva que muestre poemas del Romancero gitano de Federico García Lorca y modifique su apariencia visual en función de las diferentes metáforas.
+ +El documento HTML debe:
+<!DOCTYPE>, <html>, <head>, <body>).<pre>.No debe utilizarse ningún framework ni librería externa.
+En JavaScript se debe definir un array de objetos, donde cada objeto represente un poema y tenga al menos:
+El cambio de poema debe hacerse recorriendo este array de forma cíclica (cola circular) mediante el botón.
+Descargar poemas (click derecho guardar enlace como)
+El comportamiento de la página debe implementarse exclusivamente con DOM nativo, cumpliendo lo siguiente:
+El cálculo debe realizarse a partir del texto del poema, no con valores predefinidos.
+Lorca utiliza las metáforas y la alegoría como elemento principal sobre el que construye sus poemas, al analizar profundamente descubrimos que siempre recurre a las mismas metáforas.
+El color no se utiliza aquí solo como elemento decorativo, sino como un recurso semántico: cada color representa un símbolo literario presente en el poema.
+Desde el punto de vista técnico: - Los colores de fondo y de texto deben definirse en clases CSS. - JavaScript no decide colores, únicamente decide qué clase aplicar según el contenido del poema.
+Se debe detectar el texto del poema las siguientes palabras clave y aplicar el color de fondo correspondiente:
+El color del texto debe elegirse siempre de forma que exista contraste suficiente con el fondo y se garantice la legibilidad.
+Si el poema contiene varias palabras clave, solo debe aplicarse un único estilo, siguiendo un orden de prioridad definido previamente.
+Si el poema no contiene ninguna de estas palabras, se aplicará un estilo por defecto con colores aleatorios.
+De forma voluntaria, se puede añadir el símbolo aurora, que tendrá prioridad absoluta sobre todos los demás.
Cuando el poema contenga la palabra aurora, el fondo debe mostrar un degradado animado.
.aurora {
+ background: linear-gradient(120deg,
+ #ff005d,
+ #ff9f1c,
+ #ffee32,
+ #3cff00,
+ #00e5ff,
+ #7a00ff,
+ #ff00c8
+ );
+ background-size: 600% 600%;
+ animation: aurora 10s linear infinite;
+ color: black;
+}
+
+@keyframes aurora {
+ 0% { background-position: 0% 50%; }
+ 50% { background-position: 100% 50%; }
+ 100% { background-position: 0% 50%; }
+}Toda la página debe estar centrada horizontalmente.
+El centrado se consigue mediante:
+Desde el punto de vista conceptual:
+margin: 0 auto no centra texto, centra bloques.Para evitar que los cambios de color sean bruscos, se utiliza la propiedad transition en CSS.
Esta propiedad indica al navegador que los cambios en determinadas propiedades visuales deben hacerse de forma progresiva.
+Ejemplo conceptual:
+body {
+ transition: background-color 0.6s, color 0.6s;
+}Gracias a esta transición: - Cuando JavaScript cambia una clase o un color, - el navegador interpola automáticamente entre el color anterior y el nuevo.
+No es necesario programar animaciones en JavaScript: CSS se encarga de todo el efecto visual.
+Para buscar si determinada palabra determinada se debe utilizar la función includes de la clase string
+texto = "hoy nieva";
+
+texto.includes("nieva"); //TRUE
+texto.includes("llueve"); //FALSEPara la generacióndel color aleatorio de puede utilizar la siguiente función
+const randomColor = () => '#' + Math.floor(Math.random() * 16777215).toString(16);El recuento de versos y estrofas debe hacerse a partir del texto del poema, no con valores escritos a mano. A continuación se dan algunas pistas técnicas para abordar este problema.
+Un verso puede considerarse, a efectos prácticos en esta tarea, como una línea de texto no vacía.
+Una estrategia habitual consiste en: - Separar el texto por saltos de línea. - Eliminar las líneas vacías o formadas solo por espacios. - Contar cuántas líneas válidas quedan.
+Ejemplo orientativo:
+const versos = texto
+ .split('\n')
+ .filter(linea => linea.trim() !== '')
+ .length;Este enfoque es suficiente para la mayoría de los poemas del Romancero gitano y evita errores frecuentes.
+Una estrofa puede entenderse como un bloque de versos separado de otros bloques por una línea en blanco.
+Una posible estrategia es: - Separar el texto usando dos (o más) saltos de línea consecutivos. - Eliminar bloques vacíos. - Contar los bloques resultantes.
+Ejemplo orientativo:
+const estrofas = texto
+ .split(/\n\s*\n/)
+ .filter(bloque => bloque.trim() !== '')
+ .length;Entrega: un único archivo HTML funcional.
+Al enfrentarnos a un proyecto de cierta complejitud, el como afrontarlo resulta de cricial para el desarollo del mismo por ello a a continuación dejo un esquema de implementación modular. Sería mejor no utilizarlo, pero puede ser un buen punto de partida si no se sabe como empezar la app, no es el único proceso de implementación válido ni es más correcto que cualquier otro
+{question}
+Loading...
; + + const question = questions[currentQuestion]; + + const answers = [ + ...question.incorrectAnswers, + question.correctAnswer, + ].sort(); + + function handleAnswer(answer) { + setSelectedAnswer(answer); + } + + function nextQuestion() { + const newScore = + selectedAnswer === question.correctAnswer ? score + 1 : score; + + const isLastQuestion = currentQuestion === questions.length - 1; + + if (isLastQuestion) { + setScore(newScore); + setShowResult(true); + return; + } + + setScore(newScore); + setCurrentQuestion((prev) => prev + 1); + setSelectedAnswer(null); + } + + if (showResult) { + return ( ++ Your score: {score} / {questions.length} +
+Pokemon {id}
; + +} +``` + +Este parámetro puede utilizarse para realizar peticiones a una API. + +::: {.content-visible when-format="revealjs"} + +--- + +::: + +## Context API + +En aplicaciones grandes aparece un problema frecuente. + +Muchos componentes necesitan acceder a la **misma información**. + +Por ejemplo: + +- usuario +- tema visual +- idioma +- configuración + +Si pasamos la información mediante *props*, los datos deben atravesar muchos componentes. + +::: {.content-visible when-format="revealjs"} + +--- + +::: + +Representación conceptual: + +``` +App + └ Layout + └ Page + └ Component +``` + +Si todos necesitan `user`, debemos pasar la prop continuamente. + +Este problema se conoce como **prop drilling**. + +::: {.content-visible when-format="revealjs"} + +--- + +::: + +### Context + +React proporciona una solución llamada **Context**. + +Context permite **compartir información entre múltiples componentes** sin pasar props manualmente. + +El proceso tiene tres pasos: + +1. Crear el contexto +2. Proveer el contexto +3. Consumir el contexto + +::: {.content-visible when-format="revealjs"} + +--- + +::: + +#### Crear un contexto + +```jsx +import { createContext } from "react"; + +const UserContext = createContext(); +``` + +Esto crea un contenedor que puede almacenar información compartida. + +::: {.content-visible when-format="revealjs"} + +--- + +::: + +#### Provider + +El `Provider` permite que los componentes hijos accedan al contexto. + +```jsx +`.
+ 4. Un **botón** que permita cambiar de poema.
+
+No debe utilizarse ningún *framework* ni librería externa.
+
+
+## JavaScript
+
+### Datos
+
+En JavaScript se debe definir un **array de objetos**, donde cada objeto represente un poema y tenga al menos:
+
+- Un título.
+- El texto del poema como una cadena de texto, usando saltos de línea para los versos.
+
+El cambio de poema debe hacerse recorriendo este array de forma cíclica (cola circular) mediante el botón.
+
+[Descargar poemas](poemas.js) (click derecho guardar enlace como)
+
+
+### Manipulación del DOM
+
+El comportamiento de la página debe implementarse **exclusivamente con DOM nativo**, cumpliendo lo siguiente:
+
+- Todas las funciones deben declararse como **arrow functions**.
+- Al pulsar el botón:
+ - Se actualiza el título.
+ - Se actualiza el texto del poema.
+ - Se modifica el formato del fondo.
+ - Se recalculan y muestran:
+ - Número de versos.
+ - Número de estrofas (bloques separados por líneas en blanco).
+
+El cálculo debe realizarse a partir del texto del poema, no con valores predefinidos.
+
+
+## CSS
+
+Lorca utiliza las metáforas y la alegoría como elemento principal sobre el que construye sus poemas, al analizar profundamente descubrimos que siempre recurre a las mismas metáforas.
+
+El color no se utiliza aquí solo como elemento decorativo, sino como un recurso semántico: cada color representa un símbolo literario presente en el poema.
+
+Desde el punto de vista técnico:
+- Los **colores de fondo y de texto** deben definirse en **clases CSS**.
+- JavaScript no decide colores, únicamente decide qué clase aplicar según el contenido del poema.
+
+
+### Palabras clave y colores asociados
+
+Se debe detectar el texto del poema las siguientes **palabras clave** y aplicar el **color de fondo correspondiente**:
+
+- **guardia civil** → fondo **verde militar**
+- **sangre** → fondo **granate oscuro**
+- **caballo** → fondo **color tierra**
+- **cuchillo / navaja** → fondo **plateado**
+
+El color del texto debe elegirse siempre de forma que exista **contraste suficiente** con el fondo y se garantice la legibilidad.
+
+Si el poema contiene varias palabras clave, solo debe aplicarse **un único estilo**, siguiendo un orden de prioridad definido previamente.
+
+Si el poema no contiene ninguna de estas palabras, se aplicará un **estilo por defecto** con colores aleatorios.
+
+
+
+## Extra opcional: símbolo *aurora* 🌈
+
+De forma **voluntaria**, se puede añadir el símbolo **`aurora`**, que tendrá **prioridad absoluta sobre todos los demás**.
+
+Cuando el poema contenga la palabra `aurora`, el fondo debe mostrar un **degradado animado**.
+
+### CSS necesario para el extra
+
+```css
+.aurora {
+ background: linear-gradient(120deg,
+ #ff005d,
+ #ff9f1c,
+ #ffee32,
+ #3cff00,
+ #00e5ff,
+ #7a00ff,
+ #ff00c8
+ );
+ background-size: 600% 600%;
+ animation: aurora 10s linear infinite;
+ color: black;
+}
+
+@keyframes aurora {
+ 0% { background-position: 0% 50%; }
+ 50% { background-position: 100% 50%; }
+ 100% { background-position: 0% 50%; }
+}
+```
+
+---
+
+## Consejos
+
+### Centrado de la página (layout clásico)
+
+Toda la página debe estar centrada **horizontalmente**.
+
+El centrado se consigue mediante:
+
+- Un contenedor con un ancho máximo definido.
+- Márgenes automáticos a izquierda y derecha.
+
+Desde el punto de vista conceptual:
+
+- `margin: 0 auto` **no centra texto**, centra **bloques**.
+- El navegador reparte automáticamente el espacio sobrante a ambos lados del contenedor.
+
+
+### Animación del cambio de color
+
+Para evitar que los cambios de color sean bruscos, se utiliza la propiedad **`transition`** en CSS.
+
+Esta propiedad indica al navegador que los cambios en determinadas propiedades visuales deben hacerse de forma progresiva.
+
+Ejemplo conceptual:
+
+```css
+body {
+ transition: background-color 0.6s, color 0.6s;
+}
+```
+
+Gracias a esta transición:
+- Cuando JavaScript cambia una clase o un color,
+- el navegador interpola automáticamente entre el color anterior y el nuevo.
+
+No es necesario programar animaciones en JavaScript: **CSS se encarga de todo el efecto visual**.
+
+
+### Búsqueda de una palabra
+
+Para buscar si determinada palabra determinada se debe utilizar la función `includes` de la clase string
+
+```js
+
+texto = "hoy nieva";
+
+texto.includes("nieva"); //TRUE
+texto.includes("llueve"); //FALSE
+```
+
+
+### Generación del color aleatorio
+
+Para la generacióndel color aleatorio de puede utilizar la siguiente función
+
+```js
+const randomColor = () => '#' + Math.floor(Math.random() * 16777215).toString(16);
+```
+
+### Conteo versos y estrofas
+
+El recuento de versos y estrofas debe hacerse **a partir del texto del poema**, no con valores escritos a mano. A continuación se dan algunas **pistas técnicas** para abordar este problema.
+
+#### Conteo de versos
+
+Un verso puede considerarse, a efectos prácticos en esta tarea, como **una línea de texto no vacía**.
+
+Una estrategia habitual consiste en:
+- Separar el texto por saltos de línea.
+- Eliminar las líneas vacías o formadas solo por espacios.
+- Contar cuántas líneas válidas quedan.
+
+Ejemplo orientativo:
+
+```js
+const versos = texto
+ .split('\n')
+ .filter(linea => linea.trim() !== '')
+ .length;
+```
+
+Este enfoque es suficiente para la mayoría de los poemas del *Romancero gitano* y evita errores frecuentes.
+
+#### Conteo de estrofas
+
+Una estrofa puede entenderse como un **bloque de versos separado de otros bloques por una línea en blanco**.
+
+Una posible estrategia es:
+- Separar el texto usando dos (o más) saltos de línea consecutivos.
+- Eliminar bloques vacíos.
+- Contar los bloques resultantes.
+
+Ejemplo orientativo:
+
+```js
+const estrofas = texto
+ .split(/\n\s*\n/)
+ .filter(bloque => bloque.trim() !== '')
+ .length;
+```
+
+
+
+**Entrega:** un único archivo HTML funcional.
+
+## Recomendaciones para afrontar la tarea
+
+Al enfrentarnos a un proyecto de cierta complejitud, el como afrontarlo resulta de cricial para el desarollo del mismo por ello a a continuación dejo un esquema de implementación modular. Sería mejor no utilizarlo, pero puede ser un buen punto de partida si no se sabe como empezar la app, no es el único proceso de implementación válido ni es más correcto que cualquier otro
+
+1. Estructura de HTML básica contadores de versos y estrofas *placeholders* de poema y título y botón
+2. Formateo CSS parte estática: centrado, tamaño (todo lo que no sea color)
+3. Definir clases con colores predeterminados
+4. Lógica interna con JS
+ - Buscar palabra
+ - Contar estrofas
+ - Conteo versos
+ - Selección de clase
+ - Generar color aleatorio si procede
+5. Integración con DOM
\ No newline at end of file