web-dev-qa-db-fra.com

Composant Gatsby-Image réutilisable avec des sources d'images dynamiques

Je songe à utiliser Gatsby-Image pour mon prochain projet et je joue un peu avec.

Je l'ai fait travailler sur mon projet de test, mais j'ai ensuite trouvé un cas d'utilisation que j'aimerais utiliser de chez Gatsby un peu comme un _ <img src”image.png”> tag. Ma question est donc de savoir comment rendre le composant Gatsby réutilisable?

import React from "react"
import { StaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"
function renderImage({ file }) {
  console.log({ file })
  return <Img fluid={file.childImageSharp.fluid} />
}

// Stateless Image component which i guess will recieve src value as a prop?
// Returns a StaticQuery component with query prop and render prop. Query prop has the graphql query to recieve the images and render prop returns a renderImage function which in return, returns a Img component från Gatsby with set attributes.
const Image = () => (
  <StaticQuery
    query={graphql`
      query {
        file(relativePath: { eq: "gatsby-astronaut.png" }) {
          childImageSharp {
            fluid(maxWidth: 300) {
              ...GatsbyImageSharpFluid
            }
          }
        }
      }
    `}
    // render={data => <Img fluid={data.placeholderImage.childImageSharp.fluid} />}
    render={renderImage}
  />
)
export default Image

Mon cas d'utilisation optimal serait de faire une demande dynamique à mon chemin d'accès relatif qui est défini dans mon fichier Gatsby.config, puis de combiner l'accessoire src dans chaque Gatsby et de le faire correspondre avec toutes mes images dans mon fichier d'actifs, puis de l'afficher. Est-ce que quelqu'un d'entre vous sait si c'est possible avec?

J'ai lu dans les documents que Static Query ne peut pas prendre de variables - seulement des pages. Mais je ne veux pas que mes images soient associées à une page - je veux utiliser ce composant où je veux - comme une balise img standard.

J'espère que je me suis bien fait comprendre. Veuillez demander si vous avez des questions.

Ceci est un exemple: https://codesandbox.io/s/py5n24wk27

Merci d'avance, Erik

15
erikos93

J'ai également cherché cette réponse. J'espère que cela répond à votre question:

Le code final:

import React from 'react';
import { StaticQuery, graphql } from 'gatsby';
import Img from 'gatsby-image';

// Note: You can change "images" to whatever you'd like.

const Image = props => (
  <StaticQuery
    query={graphql`
      query {
        images: allFile {
          edges {
            node {
              relativePath
              name
              childImageSharp {
                fluid(maxWidth: 600) {
                  ...GatsbyImageSharpFluid
                }
              }
            }
          }
        }
      }
    `}
    render={data => {
      const image = data.images.edges.find(n => {
        return n.node.relativePath.includes(props.filename);
      });
      if (!image) {
        return null;
      }

      //const imageSizes = image.node.childImageSharp.sizes; sizes={imageSizes}
      return <Img alt={props.alt} fluid={image.node.childImageSharp.fluid} />;
    }}
  />
);

export default Image;

Utilisation de l'image:

import Image from '../components/Image';
<div style={{ maxWidth: `300px` }}>
    <Image alt="Gatsby in Space" filename="gatsby-astronaut.png" />
</div>

Explication

Parce que StaticQuery ne prend pas en charge l'interpolation de chaînes dans son littéral de modèle, nous ne pouvons pas vraiment lui passer d'accessoires. Au lieu de cela, nous essaierons de gérer la vérification des accessoires dans la partie Rendu de StaticQuery.

Avertissements

Je ne suis pas sûr à 100% si cela affecte le temps de compilation puisque nous numérisons toutes les images. Si c'est le cas, faites-le moi savoir!

Mise à jour: si vous avez plusieurs images, la taille du bundle peut devenir assez importante car cette solution numérise TOUTES les images.

Personnalisation supplémentaire

Vous pouvez ajuster le code pour afficher une image d'espace réservé si aucun accessoire n'est transmis.

Alternatives

Cela dit, il existe une autre façon de résoudre ce problème mais avec un peu plus de travail/code.

Sources

  • J'ai modifié le code de cet article . (Veuillez noter que l'article utilisait du code obsolète.)
18
RodrigoLeon

Donc, @RodrigoLeon, j'ai remarqué qu'en le faisant dans votre approche, cela entraînerait une augmentation drastique de la taille du paquet. Surtout si disons que vous avez plus de 50 images. Parce que chaque fois que vous l'utilisez et parcourez toutes les images, vous créez des références à celles-ci dans le fichier de composant. Je ne recommanderais donc pas de procéder de cette façon. Malheureusement, d'après ce que je peux rassembler, la meilleure solution consiste à écrire des fichiers js individuels pour les images.

3
Dawson Walker