简体   繁体   中英

React w Gatsby: implemented sequential fade-in animation for gallery but it doesn't work right after being deployed

The source code is here: https://codesandbox.io/s/gatsby-starter-default-nvhl7

And the deployed site is here: https://csb-nvhl7-24q4bchuz.now.sh/

The effect I am trying to achieve is simple and straightforward.

First I used this query to load all the image files from the images folder

const data = useStaticQuery(graphql`
    query {
      allFile(
        filter: {
          extension: { regex: "/(jpg)|(jpeg)|(png)/" }
          sourceInstanceName: { eq: "images" }
        }
      ) {
        edges {
          node {
            childImageSharp {
              fluid(maxWidth: 800, quality: 95) {
                aspectRatio
                src
                srcSet
                originalName
                srcWebp
                srcSetWebp
                sizes
              }
            }
          }
        }
      }
    }

Then I have a gallery component to display them by dividing these images into three groups, and we can use project1 , project2 and project3 to navigate between them.

const Gallery = ({ minWidth }) => {
  let refs = {}

  const allPics = Image().map(({ childImageSharp }, i) => {
    // eslint-disable-next-line react-hooks/rules-of-hooks
    refs[i] = useRef(null)
    childImageSharp.index = i
    return childImageSharp
  })

  const firsload = allPics.slice(0, 5)
  const secload = allPics.slice(5, 10)
  const third = allPics.slice(10)

  const [imgs, setImgs] = useState(firsload)

  const thumbnails = imgs.map(img => img.fluid.srcSet.split(" ")[0])

  return (
    <>
      <ProjectsContainer>
        <Project
          onClick={() => {
            setImgs(firsload)
          }}
        >
          Project 1.
        </Project>
        <Project
          onClick={() => {
            setImgs(secload)
          }}
        >
          Project 2.
        </Project>
        <Project
          onClick={() => {
            setImgs(third)
          }}
        >
          Project 3.
        </Project>
      </ProjectsContainer>
      <Mansory gap={"0em"} minWidth={minWidth}>
        {imgs.map((img, i) => {
          return (
            <PicContainer key={img.index}>
              <Enlarger
                src={thumbnails[i]}
                enlargedSrc={img.fluid.src}
                index={img.index}
                orderIndex={i}
                onLoad={() => {
                  refs[img.index].current.toggleOpacity(1) <-- use ref to keep track of every Enlarger 
                }}
                ref={refs[img.index]}
              />
            </PicContainer>
          )
        })}
      </Mansory>
    </>
  )
}

For every Enlarger that gets rendered by the Gallery , they are a zoom image component

import Img from "react-image-enlarger"

class Enlarger extends React.Component {
  state = { zoomed: false, opacity: 0 } <--- initially every image's opacity is 0, then it shows up by being toggled opacity 1

  toggleOpacity = o => {
    this.setState({ opacity: o })
  }

  render() {
    const { index, orderIndex, src, enlargedSrc, onLoad } = this.props
    return (
      <div style={{ margin: "0.25rem" }} onLoad={onLoad}> <-- where we toggle the opacity when the element is onloaded
        <Img
          style={{
            opacity: this.state.opacity,
            transition: "opacity 0.5s cubic-bezier(0.25,0.46,0.45,0.94)",
            transitionDelay: `${orderIndex * 0.07}s`,
          }}
          zoomed={this.state.zoomed}
          src={src}
          enlargedSrc={enlargedSrc}
          onClick={() => {
            this.setState({ zoomed: true })
          }}
          onRequestClose={() => {
            this.setState({ zoomed: false })
          }}
        />
      </div>
    )
  }
}

And I have made it clear in the code snippet where I implemented the sequential fade-in animation by using ref to control every Enlarger 's toggleOpacity method.

This code works great on localhost, ie during development. You can try the codesandbox link above to see it. However the bug appears only when the page is deployed. . Click on the deployed version ( https://csb-nvhl7-24q4bchuz.now.sh/ ) you can see that when browser first loading the page, some pictures are missing, because their opacity are still 0, which I suspect is because refs[img.index].current.toggleOpacity(1) somehow didn't get called on the image when they are onloaded. However the weird thing is, when you navigate between the projects , there's no problems at all with this animation and opacity change, they are normal. And when you refresh the page, the problem shows up again.

I been struggling with this problem for days and couldn't figure out why. Also although here I used ZEIT Now to deploy the site, the problem didn't go away when I used Netlify to deploy.

Its not because of deployment, in Production Your images taking more time to load. See the image network call in the browser

除了Kishore的答案之外,您可能希望在页面加载后进行查询(可能在componentDidMount中)并使用setState触发响应以在内容完全加载后重新呈现。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM