useContext

crear Contexto: (Contexto.js)

import { createContext } from "react";

const Contexto=createContext("valor por defecto");
export default Contexto;

Proveer de contexto: (App.js)


import './App.css';
import React from 'react';
import ComPadre from './componentes/ComPadre';
import Contexto from './componentes/Contexto';
function App() {

  return (
    <div className="App">
      <Contexto.Provider value="Hola contexto">
        <ComPadre texto="Hola" />
      </Contexto.Provider>
      
    </div>
  );
}

export default App;

Arbol de componentes: (Compadre,comhijo1,comhijo2)

import ComHijo1 from "./ComHijo1";
function ComPadre({ texto }) {

    return <ComHijo1 texto={texto}/>;
}

export default ComPadre;
import ComHijo2 from "./ComHijo2";
function ComHijo1({ texto }) {

    return <ComHijo2 texto={texto}/>;
}

export default ComHijo1;
import ComHijo3 from "./ComHijo3";
function ComHijo2({ texto }) {

    return <ComHijo3 texto={texto}/>;
}

export default ComHijo2;

Consumir el contexo (ComHijo3)

import { useContext } from "react";
import Contexto from "./Contexto";
function ComHijo3({ texto }) {
    const textoContexto = useContext(Contexto);
    console.log(textoContexto)
    return (<>
        <h1>{texto}</h1>
        <p> Esto viene desde las propiedades por goteo</p>
        <h1>{textoContexto}</h1><p> Esto viene del contexto</p>
    </>)
}

export default ComHijo3;

Solución 2

import Cabecera from './Cabecera';
import Boton from './Boton';

function Bloque({ texto }) {
    const pinchar=()=>{
        console.log("Has pinchado el botón "+texto)
    }
    // Paso el evento del padre al hijo
    return <div>
        <Cabecera texto={texto} />
        <Boton texto="Pincha aquí" evento={pinchar}/> 
    </div>;
}

export default Bloque;
function Boton({ texto,evento }) {

    return <button onClick={evento}>{texto}</button>;
}

export default Boton;

Solución 1 evento botón

Pasar la información del padre al hijo
En bloque pasamos el texto al botón

import Cabecera from './Cabecera';
import Boton from './Boton';

function Bloque({ texto }) {

    // Paso la información del padre al hijo
    return <div>
        <Cabecera texto={texto} />
        <Boton texto="Pincha aquí" bloque={texto}/> 
    </div>;
}

export default Bloque;
function Boton({ texto,bloque }) {

    return <button onClick={()=>pinchar(bloque)}>{texto}</button>;
}
const pinchar=(texto)=>{
    console.log("Has pinchado el botón "+texto)
}
export default Boton;

Pasar una función como propiedad

App.js

import './App.css'; // Estilos propios del componente 
import Tarjeta from './componentes/Tarjeta'; // Importo la tarjeta

const foo=(elemento)=>{
  console.log("Has pinchado en " + elemento.alt)
    if (elemento.alt === "Marie Curie") {
      elemento.src = "/img/ok.jpg"
    } 
}
function App() {

  // Devuelvo un div con las tarjetas que quiera
  // la Tarjeta tiene unas propiedades que se pasan al componente
  // Pasamos el nombre y la url de la imagen
  return (
    <div className="App">
      <h1>¿Quien descubrió el radio?</h1>
      <Tarjeta nombre="Einstein" correcta="Marie Curie" foo={foo}/>
      <Tarjeta nombre="Marie Curie" correcta="Marie Curie"  foo={foo}/>
      <Tarjeta nombre="Schrodinger" correcta="Marie Curie" foo={foo}/>
    </div>
  );
}

export default App;

Tarjeta.js

import Foto from './Foto'; // Importo Foto
import Cabecera from './Cabecera'; // Importo Cabecera


// Tarjeta le paso las propiedades nombre y url
// Esto va dentro de props pero uso destructuring
function Tarjeta({nombre, correcta,foo}) {
    // En el div es donde pongo la clase, porque es elemento html
    // Uso los componentes Cabecera y Foto
    return (
        <div className="tarjeta">
            <Cabecera  nombre={nombre} correcta={correcta}/>
            <Foto descripcion={nombre}  foo={foo}/>
        </div>
    )
}

export default Tarjeta;

Foto.js

function Foto({descripcion, foo}) {
    let ruta='/img/'
    let nombre=descripcion.toLowerCase().replaceAll(" ","")+".jpg"
    return <img onClick={(evt)=>{foo(evt.target)}} className="foto" src={ruta+nombre} alt={descripcion} />
}

export default Foto;

Ejemplos eventos

App.js

import './App.css'; // Estilos propios del componente 
import Tarjeta from './componentes/Tarjeta'; // Importo la tarjeta


function App() {

  // Devuelvo un div con las tarjetas que quiera
  // la Tarjeta tiene unas propiedades que se pasan al componente
  // Pasamos el nombre y la url de la imagen
  return (
    <div className="App">
      <h1>¿Quien descubrió el radio?</h1>
      <Tarjeta nombre="Einstein" correcta="Marie Curie" />
      <Tarjeta nombre="Marie Curie" correcta="Marie Curie"/>
      <Tarjeta nombre="Schrodinger" correcta="Marie Curie"/>
    </div>
  );
}

export default App;

Tarjeta.js

import Foto from './Foto'; // Importo Foto
import Cabecera from './Cabecera'; // Importo Cabecera


// Tarjeta le paso las propiedades nombre y url
// Esto va dentro de props pero uso destructuring
function Tarjeta({nombre, correcta}) {
    // En el div es donde pongo la clase, porque es elemento html
    // Uso los componentes Cabecera y Foto
    return (
        <div className="tarjeta">
            <Cabecera  nombre={nombre} correcta={correcta}/>
            <Foto descripcion={nombre}/>
        </div>
    )
}

export default Tarjeta;

Cabecera.js

const comprobar = (objeto, correcta) => {
    
    console.log("Has pinchado en " + objeto.innerHTML)
    if (objeto.innerHTML === correcta) {
        objeto.innerHTML = "Muy BIEN"
    } else {
        objeto.innerHTML = "INCORRECTO"
    }
}

function Cabecera({ nombre, correcta }) {

    return <h1 onClick={(event) => { comprobar(event.target, correcta) }} >{nombre}</h1>;
}

export default Cabecera;

Minipágina React

Yo tengo varias cosas.

En public tengo una carpeta img con diferentes imágenes. Si dentro de mi programa pongo ruta absoluta ‘/img/…’ React va a buscar esa imagen en la carpeta.

Tengo mi App como siempre, que en general es el punto de entrada de cualquier web.

import './App.css'; // Estilos propios del componente 
import Tarjeta from './componentes/Tarjeta'; // Importo la tarjeta


function App() {

  // Devuelvo un div con las tarjetas que quiera
  // la Tarjeta tiene unas propiedades que se pasan al componente
  // Pasamos el nombre y la url de la imagen
  return (
    <div className="App"> 
      <Tarjeta nombre="Einstein" url='/img/einstein.jpg' />
    </div>
  );
}

export default App;

El componente ‘Tarjeta’ es un componente compuesto, importa otros componentes:

import Foto from './Foto'; // Importo Foto
import Cabecera from './Cabecera'; // Importo Cabecera

// Tarjeta le paso las propiedades nombre y url
// Esto va dentro de props pero uso destructuring
function Tarjeta({nombre, url}) {
    // En el div es donde pongo la clase, porque es elemento html
    // Uso los componentes Cabecera y Foto
    return (
        <div className="tarjeta">
            <Cabecera nombre={nombre}/>
            <Foto  descripcion={nombre} url={url}/>
        </div>
    )
}

export default Tarjeta;

Cabecera.js

function Cabecera({nombre}) {
    return <h1>{nombre}</h1>;
}

export default Cabecera;

Fotos.js

function Foto({url,descripcion}) {
    return <img className="foto" src={url} alt={descripcion} />
}

export default Foto;

Ejemplos React

App.js

import logo from './logo.svg';
import './App.css';
import Foto from './componentes/Foto';

function App() {
  return (
    <div className="App">
     <Foto descripcion="Einstein" url="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d3/Albert_Einstein_Head.jpg/330px-Albert_Einstein_Head.jpg"/>
     <Foto descripcion="Marie Curie" url="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQbLv9v4IWJ5tPUsHQwLsWLIPhIpznuTZGsNBfoHqXYNLxPSLHf"/>
    </div>
  );
}

export default App;

/componentes/Foto.js

function Foto({url,descripcion}) {
    return <img className="foto" src={url} alt={descripcion} />
}

export default Foto;

Más React

import logo from './logo.svg';
import './App.css';
const Saludo = ({nombre,apellidos="",edad=0}) => {
  console.log(nombre,apellidos,edad)
  return <h1>Hola {nombre+" "+apellidos}, qué tal?</h1>;
}
const gestionarClick = (evt) => {
  
  console.log("clickado",evt);
}
const Despedida = () => {
  let tipo = "compañero"
  return (
    <>
      <h2  onClick={gestionarClick} className='destacado'>Adios {tipo.toUpperCase()}</h2>
      <p >Nos vemos otro día</p>
      <br />
      <img onClick={gestionarClick} className='App-logo' src={logo} />
    </>
  );
}
function App() {
  return (
    <div className="App">
      <Saludo nombre="Juan" apellidos="Pérez" edad="30" />
      <Despedida />
      <Saludo nombre="Ana" />
    </div>
  );
}

export default App;

Ejemplos React

const Saludo = (props) => {
  console.log("Hola que tal")
  return <h1>Hola {props.nombre}, qué tal?</h1>;
}
const gestionarClick = () => {
  console.log("clickado");
}
const Despedida = () => {
  let tipo = "compañero"
  return (
    <>
      <h2 className='destacado'>Adios {tipo.toUpperCase()}</h2>
      <p onClick={gestionarClick}>Nos vemos otro día</p>
      <br />
      <img className='App-logo' src={logo} />
    </>
  );
}
function App() {
  return (
    <div className="App">
      <Saludo nombre="Juan" />
      <Despedida />
      <Saludo nombre="Ana" />
    </div>
  );
}

Solución ejercicios módulos

utiliades.js

function ordenar(a, b) {
    if (a > b) {
        return [b, a];
    } else {
        return [a, b];
    }
}

function ordenarT(a, b) {
    return a > b ? [b, a] : [a, b];
}

function iniciales(nombre,apellidos){
    return [nombre.at(0)+apellidos.at(0),apellidos.at(0)+nombre.at(0)]
}

export {ordenar,ordenarT,iniciales}

test.js

import { ordenar,iniciales } from "./utilidades.js";

let [a,b]=ordenar(1,8);

console.log(a,b)

let [ini1,ini2]=iniciales("Juan","Pérez");
console.log(ini1)
console.log(ini2)