Ejemplo de estados con contador y texto

import React, { useState } from 'react';

const Contador = () => {
    // Quiero variables dentro de una página de react tengo que utilizar estado
    const [contador, setContador] = useState(0);
    const [cadena, setCadena] = useState("")
  
    
    const incrementarContador = () => {
        setContador(contador + 1);
        setCadena("")
    };
    const decrementarContador = () => {
        if (contador>0) {
            setContador(contador - 1);
            
        }else{
            setCadena("No puedes poner número negativos")
        }
        
    };
    return (
        <div>
            <p>Contador: {contador}</p>
            <p> {cadena}</p>
            <button onClick={incrementarContador}>Incrementar</button>
            <button onClick={decrementarContador}>Decrementar</button>
            <button onClick={() => setContador(0)}>Reset</button>
        </div>
    );
};
export default Contador;

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;

Mini ejercicio react

Descargar el código de la cesta de la compra:

https://github.com/PacktPublishing/React—The-Complete-Guide-includes-Hooks-React-Router-and-Redux-Second-Edition/tree/main/Section%2011/code/12-finished

Y añadimos las siguientes mejoras:

1.- Botón en la cesta para eliminar completamente un producto
2.- Si la compra es superior a 1000 que se muestre un aviso de que se puede pagar en tres plazos
3.- Poder filtrar las carnes por el nombre.

Ejercicio useReducer

Vamos a crear un formulario con dos inputs de type number y cuatro botones para sumar, restar, dividir y multiplicar. El resultado se mostrará en un div.

Para la lógica usaremos useReducer