question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Sorting an array of objects does not update img src

See original GitHub issue

Description

This only occurs in a production build.

When providing an array of objects that include an image source url to a component, you would expect the properties to display per object.

Shuffling the array randomizes everything, but React seems to re-render everything other than the img tag.

Various sort methods to randomize the array have been tried with the same result.

Code example: https://github.com/corymcdaniel/react-sorted-images Live example: https://sorted-images-bug.netlify.com/

Refresh the page a few times and you’ll see that the text changes but the image does not.

I’ve tried this in a CRA project and it doesn’t reproduce the issue, so I’m assuming this has to do with the default Gatsby build. I’ve tried adding keys to the img tag, putting a hash and key on the img src, shuffling before or after mapping, all with the same result.

Steps to reproduce

  • Create an array of objects that include a url to an image.
  • Shuffle array
  • Map items to a component that displays the image and any text properties

Expected result

A random list that displays an image and accompanying text

Actual result

Images do not update to their associated text. If you view page-source, it looks correct, but the re-render does not update the img src

Environment

  System:
    OS: macOS 10.15.2
    CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 10.16.0 - ~/.nvm/versions/node/v10.16.0/bin/node
    Yarn: 1.17.3 - ~/.nvm/versions/node/v10.16.0/bin/yarn
    npm: 6.13.4 - ~/.nvm/versions/node/v10.16.0/bin/npm
  Languages:
    Python: 2.7.16 - /usr/bin/python
  Browsers:
    Chrome: 79.0.3945.117
    Firefox: 72.0.1
    Safari: 13.0.4
  npmPackages:
    gatsby: ^2.18.12 => 2.18.12 
    gatsby-image: ^2.2.34 => 2.2.34 
    gatsby-plugin-manifest: ^2.2.31 => 2.2.31 
    gatsby-plugin-offline: ^3.0.27 => 3.0.27 
    gatsby-plugin-react-helmet: ^3.1.16 => 3.1.16 
    gatsby-plugin-sharp: ^2.3.5 => 2.3.5 
    gatsby-source-filesystem: ^2.1.40 => 2.1.40 
    gatsby-transformer-sharp: ^2.3.7 => 2.3.7 
  npmGlobalPackages:
    gatsby-cli: 2.7.46

I’ve been pulling my hair out on this one.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:3
  • Comments:13

github_iconTop GitHub Comments

1reaction
jonniebigodescommented, Mar 2, 2020

@corymcdaniel no need to be sorry and no thanks are required, just wanted to present a cleaner solution for your issue and with that not only help you but someone else that comes across this issue.

1reaction
jonniebigodescommented, Feb 23, 2020

@corymcdaniel this issue kept bugging me for a bit and in the meantime i put it on the “back burner” and yesterday i decided to revisit it with a fresh pair of eyes. With that in mind it hit me we could do better than this and avoid the “clunkyness” of using the effect and the timeout.

Below are the steps i took to address this:

  • Re cloned your repo and installed the dependencies

  • Installed @loadable/babel-plugin, @loadable/component and @loadable/webpack-plugin. These additions with the code changes i did will “offload” part of the app to the client side, ensuring the conjunction of generating random numbers and setting the images will function better. You can read more about it here, checked the Gatsby documentation that mentions this approach and component and it’s a bit off, as the example could be improved for better understandability.

  • After the installation went through i changed gatsby-node.js to the following:

const loadablePlugin=require('@loadable/webpack-plugin');


exports.onCreateWebpackConfig =({ actions })=>{
    actions.setWebpackConfig({
        plugins: [new loadablePlugin()]
    })
}

What is happening here is nothing more than injecting the @loadable/webpack-plugin into the already existing webpack configuration for Gatsby.

  • Grabbed a couple of images i usually use for issues that will involve working with images into the static folder more even to expand the set a bit.

  • Created a new component called LoadableImageList.js with the following:

import React from "react"
import ImageList from "../components/ImageList"
const imageList = [
  {
    src: "https://images.pexels.com/photos/3584443/pexels-photo-3584443.jpeg",
    imgId: "3584443",
    text: "bridge",
  },
  {
    src: "https://images.pexels.com/photos/3590401/pexels-photo-3590401.jpeg",
    imgId: "3590401",
    text: "pasta",
  },
  {
    src: "https://images.pexels.com/photos/3585073/pexels-photo-3585073.jpeg",
    imgId: "3585073",
    text: "people",
  },
  {
    src: "first-image.jpg",
    imgId: "3585001",
    text: "lemurs",
  },
  {
    src: "second-image.png",
    imgId: "3585002",
    text: "chuck",
  },
  {
    src: "third-image.jpg",
    imgId: "3585003",
    text: "touch",
  },
  {
    src: "fourth-image.jpg",
    imgId: "3585004",
    text: "tree",
  },
]

const ImagesList = () => {
  const sortedList = [...imageList].sort(() => Math.random() - 0.5)
  console.log(`sortedList:${JSON.stringify(sortedList, null, 2)}`)  // this console.log() is intentional to test if the randomness happens.
  return (
    <>
      <ImageList items={sortedList} />
    </>
  )
}
export default ImagesList

This is nothing more than your previous implementation of the code used in pages\index.js

  • Updated pages\index.js to the following:
import React from "react"
import Loadable from "@loadable/component"
import Layout from '../components/layout'
const LoadableImageList = Loadable(() =>
  import("../components/LoadableImageList")
)

const IndexPage = () => (
  <Layout>
    <h1>Random Images</h1>
    <ul>
      <li>443: bridge</li>
      <li>401: pasta</li>
      <li>073: people</li>
      <li>001: lemurs</li>
      <li>002: chuck</li>
      <li>003: touch</li>
      <li>004: tree</li>
    </ul>
    <div>
      <LoadableImageList />
    </div>
  </Layout>
)

export default IndexPage
  • Issued a production build with yarn build && yarn serve and opened up http://localhost:9000 and i’m presented with the following:

corey_v2_1

  • Refreshed the page once more and i’m presented with:

corey_v2_2

It’s still not ideal, but it removes the need of the code/logic that i originally posted.

I don’t know how far along you moved since this, but if you want to test it out, just let me know if this worked for you. Sounds good?

Read more comments on GitHub >

github_iconTop Results From Across the Web

sorting array of objects and updating state - Stack Overflow
The function is running just fine. When I console.log the employees array, it comes out exactly as I want in alphabetical order by...
Read more >
Filtering, Sorting, and Searching in Arrays With Vue.js - Medium
Learn how to sort, filter, and search in arrays with Vue.js. We will use concise code to effectively work with arrays.
Read more >
Array.prototype.sort() - JavaScript - MDN Web Docs
The sort() method sorts the elements of an array in place and returns the reference to the same array, now sorted. The default...
Read more >
Sort React Components Using .sort() - In Plain English
A guide on the process of rendering child components from an array of objects and creating a Sort button using React.
Read more >
HTML DOM Image src Property - W3Schools
Note: The src property can be changed at any time. However, the new image inherits the height and width attributes of the original...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found