I am creating a webpage with Gatsby, Gatsby Image gallery and [Simple React Lightbox][1]. My goal is to make gallery image automatically open inside if the corresponding query is entered in the URL.
For example: when "example.com/images?id=0" is selected the first image will automatically open up. When "example.com/imades?id=1" is entered the second image will automatically open etc.
I tried using Simple React Lightbox [hooks][2] but the problem right now is that the image will open only when onClick event is triggered.
I tried getElementsByClassName.click(), useEffect and useRef but so far could not find working solution.
How can I make images open automatically when URL with specific query is selected?
Here is my gallery code
import * as React from "react"
import { graphql } from "gatsby"
import { GatsbyImage } from "gatsby-plugin-image"
import SimpleReactLightbox, { SRLWrapper } from "simple-react-lightbox"
import { useLightbox } from "simple-react-lightbox"
import Layout from "../components/layout"
import Seo from "../components/seo"
import Buttons from "../components/Buttons"
function Images({ data }) {
const { t } = useTranslation()
const images = data.allFile.edges
const { openLightbox } = useLightbox()
const queryParams = new URLSearchParams(window.location.search)
const term = queryParams.get("id")
return (
<Layout>
<Seo title="Portfolio" />
<section>
<div className="container">
<SimpleReactLightbox>
<SRLWrapper>
<div className="row">
{images.map((image, i) => (
<div
className="img-col col-sm-12 col-md-6 col-lg-3"
key={image.node.id}
>
<a
href={image.node.publicURL}
target="_blank"
rel="noreferrer"
>
<GatsbyImage
className="ratio ratio-1x1"
image={image.node.childImageSharp.gatsbyImageData}
alt={`https://example.com/images/?id=${ i}`}
/>
</a>
</div>
))}
</div>
</SRLWrapper>
<Buttons className="shared-img" term={term} />
</SimpleReactLightbox>
</div>
</section>
</Layout>
)
}
export default Images
Here is Buttons code
import { useLightbox } from "simple-react-lightbox"
import React from "react"
export default function Buttons({ term }) {
const { openLightbox } = useLightbox()
return (
<>
<button className="shared-img" onClick={() => openLightbox(term - 1)}>
Open the {term} image
</button>
</>
)
}
Thanks! [1]: https://github.com/michelecocuccio/simple-react-lightbox [2]: https://github.com/michelecocuccio/simple-react-lightbox#hooks
CodePudding user response:
You can simply include src field while fetching the image data like this.
query {
blogPost(id: { eq: $Id }) {
title
body
avatar {
childImageSharp {
gatsbyImageData(width: 200)
}
src
}
}
}
src field is the url data which you can pass to the React Lightbox.
CodePudding user response:
You need to use the useEffect hook to get the URL parameters in order to get the id. If it exists, you need to trigger the openLightbox action.
This approach is much more fluent and intuitive rather than simulating a click when there isn't. You will be "faking" the action.
Something like:
import * as React from "react"
import { graphql } from "gatsby"
import { GatsbyImage } from "gatsby-plugin-image"
import SimpleReactLightbox, { SRLWrapper } from "simple-react-lightbox"
import { useLightbox } from "simple-react-lightbox"
import Layout from "../components/layout"
import Seo from "../components/seo"
import Buttons from "../components/Buttons"
function Images({ data }) {
const { t } = useTranslation()
const images = data.allFile.edges
const { openLightbox } = useLightbox()
const queryParams = new URLSearchParams(window.location.search)
const term = queryParams.get("id")
useEffect(()=> {
const urlParams = new URLSearchParams(window.location.search);
const id= urlParams.get('id')
if(Number.isInteger(id)){
openLightbox(id)
}
}, [])
return (
<Layout>
<Seo title="Portfolio" />
<section>
<div className="container">
<SimpleReactLightbox>
<SRLWrapper>
<div className="row">
{images.map((image, i) => (
<div
className="img-col col-sm-12 col-md-6 col-lg-3"
key={image.node.id}
>
<a
href={image.node.publicURL}
target="_blank"
rel="noreferrer"
>
<GatsbyImage
className="ratio ratio-1x1"
image={image.node.childImageSharp.gatsbyImageData}
alt={`https://example.com/images/?id=${ i}`}
/>
</a>
</div>
))}
</div>
</SRLWrapper>
<Buttons className="shared-img" term={term} />
</SimpleReactLightbox>
</div>
</section>
</Layout>
)
}
export default Images
The key part is:
useEffect(()=> {
const urlParams = new URLSearchParams(window.location.search);
const id= urlParams.get('id')
if(Number.isInteger(id)){
openLightbox(id)
}
}, [])
With the first two lines you are getting the URL parameter id.
The following line:
Number.isInteger(id)
Is interesting because if you just check for the id, the id=0 will be evaluated as a falsy value, so you need to check if the id is an integer.
After that, you just need to call your lightbox function.
