19 - Mostrar imágenes localizadas en la carpeta src

Si colocamos las imágenes dentro de la carpeta 'src', React las empaqueta en el proyecto. Esto significa que cuando crea su aplicación para la producción, las imágenes se agruparán y se minimizarán.

Luego las imágenes se agregan haciendo uso de la palabra clave 'import' o 'require'

import

Problema

Crear una aplicación que muestre una bandera de un país una a la vez, permitir con dos botones cambiar a la siguiente o anterior bandera. Localizar las imágenes en la carpeta 'src'.

  1. Como primer paso creamos una aplicación con create-react-app:

    npx create-react-app proyecto019
    
  2. Creamos en la carpeta 'src' una subcarpeta llamada 'imagenes' y en la misma almacenamos 8 imágenes de banderas:

    imagenes de banderas en la carpeta src react
  3. Modificamos el archivo App.js:

    App.js

    import {useState} from 'react'
    import argentina from './imagenes/argentina.png';
    import bolivia from './imagenes/bolivia.png';
    import brasil from './imagenes/brasil.png';
    import chile from './imagenes/chile.png';
    import colombia from './imagenes/colombia.png';
    import peru from './imagenes/peru.png';
    import uruguay from './imagenes/uruguay.png';
    import venezuela from './imagenes/venezuela.png';
    
    function App() {
      const banderas = [argentina, bolivia, brasil, chile, colombia, peru, uruguay, venezuela];
      const [nroBandera, setNroBandera] = useState(0)
    
      function banderaSiguiente() {
        if (nroBandera < banderas.length - 1) {
          setNroBandera(nroBandera + 1)
        }
      }
    
      function banderaPrevia() {
        if (nroBandera > 0) {
          setNroBandera(nroBandera - 1)
        }
      }
    
      return (
        <div>
          <h1>Banderas de paises Latinoamericanos</h1>
          <p><img src={banderas[nroBandera]} alt="argentina" /></p>
          <p>
            <input type="button" value="<" onClick={banderaPrevia} />
            <input type="button" value=">" onClick={banderaSiguiente} />
          </p>
        </div>
      );
    }
    
    export default App;
    

    Importamos cada imagen con la palabra clave import y hacemos referencia al archivo de la imágen:

    import argentina from './imagenes/argentina.png';
    import bolivia from './imagenes/bolivia.png';
    import brasil from './imagenes/brasil.png';
    import chile from './imagenes/chile.png';
    import colombia from './imagenes/colombia.png';
    import peru from './imagenes/peru.png';
    import uruguay from './imagenes/uruguay.png';
    import venezuela from './imagenes/venezuela.png';
    

    Creamos un arreglo con la referencia a cada imagen:

      const banderas = [argentina, bolivia, brasil, chile, colombia, peru, uruguay, venezuela];
    

    Definimos un Hook de estado con el número de subíndice del arreglo que indicará la bandera visible actual:

      const [nroBandera, setNroBandera] = useState(0)
    

    Mostramos la imagen:

          <p><img src={banderas[nroBandera]} alt="argentina" /></p>
    

    Luego según el botón que se presiona llamamos a la función respectiva:

          <p>
            <input type="button" value="<" onClick={banderaPrevia} />
            <input type="button" value=">" onClick={banderaSiguiente} />
          </p>
    

    Las dos funciones modifican ea bandera seleccionada:

      function banderaSiguiente() {
        if (nroBandera < banderas.length - 1) {
          setNroBandera(nroBandera + 1)
        }
      }
    
      function banderaPrevia() {
        if (nroBandera > 0) {
          setNroBandera(nroBandera - 1)
        }
      }
    
    imagenes de banderas en la carpeta src react

    Podemos probar ahora la aplicación que muestra las imágenes localizadas en la carpeta public/imagenes/: aquí

    Recordar que si subimos nuestra aplicación a una subcarpeta de nuestro servidor debemos modificar el archivo 'package.json', agregando dicho path:

    {
      "name": "proyecto019",
      "homepage": "https://www.scratchya.com.ar/reactya/proyecto018/",
      "version": "0.1.0",
      "private": true,
      ....
    

require

Vamos a resolver el mismo problema pero empleando ahora require.

Podemos realizar los cambios en el mismo problema anterior, ya que las imágenes las vamos a recuperar de la misma carpeta.

Modificamos el archivo App.js:

App.js

import { useState } from 'react'

function App() {
  const banderas = ["argentina.png", "bolivia.png", "brasil.png", "chile.png", "colombia.png", "peru.png", "uruguay.png", "venezuela.png"]
  const [indice, setIndice] = useState(0)

  function banderaSiguiente() {
    if (indice < banderas.length - 1) {
      setIndice(indice + 1)
    }
  }

  function banderaPrevia() {
    if (indice > 0) {
      setIndice(indice - 1)
    }
  }

  return (
    <div>
      <h1>Banderas de paises Latinoamericanos</h1>
      <p><img src={require(`./imagenes/${banderas[indice]}`)} alt="bandera" /></p>
      <p>
        <input type="button" value="<" onClick={banderaPrevia} />
        <input type="button" value=">" onClick={banderaSiguiente} />
      </p>
    </div>
  );
}

export default App;

No disponemos ahora un import por cada imagen, sino mediante la función require indicamos el path y el nombre del archivo directamente, en nuestro caso lo extraemos del arreglo 'banderas', dependiendo del valor de la variable 'indice':

      <p><img src={require(`./imagenes/${banderas[indice]}`)} alt="bandera" /></p>