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.

Random wrong DOM elements order

See original GitHub issue

Hi there,

I’m seeing incorrect ordering of DOM elements in Firefox on Mac when rendering the below component. It’s being rendered inside a Suspense and a fragment if this helps.

const CookieWidget = ({
  type = "banner",
  location = "bottom",
  onAccept = noop,
  backdrop = false,
  ...props
}) => {
  const [Widget, widgetProps] = useCookieWidget(type, location);

  return (
    <>
      {!!backdrop && <Backdrop show />}
      <Widget {...props} {...widgetProps} onAccept={onAccept} />
    </>
  );
};

This is the screenshot from rendered DOM elements: image

They should be rendered the other way around, the current order makes the backdrop cover the widget. Any help? Maybe I should provide more code parts? The weird thing is that sometimes it renders in the correct order, usually the first time after a hard refresh. Consecutive soft refreshing causes wrong order.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:2
  • Comments:14 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
mikekasprzakcommented, Sep 17, 2022

I’m upgrading a Preact 8 codebase to Preact X, and I also ran into this unusual DOM order behavior. I’m sharing how I worked around the issue, though it’s not clear to me why the old code didn’t work.

After rewriting/fixing my blog feed code, additional posts that were loaded (appended) to my feed array would be rendered in a strange order: one would get added to the end of the output, and the rest would get added to the front. If I was to console.log or view it in the Preact Dev Tools, the order would be correct. It’s only the DOM that was wrong.

Anyway, like @olliekav above I solved my problem by wrapping my output in another tag (in my case, a Fragment).

render( props, state ) {
  const {feed} = state; // feed is an array of blog posts to be drawn in order. the array grows over time
  let content = [];  // an array of outputs we build below

  // Before
  //content = [...content, ...feed.map(this.makeFeedItem)];

  // After
  content.push(<Fragment>{feed.map(this.makeFeedItem)}</Fragment>);

  // This button disappears after you click it, and returns after the feed finishes loading
  if (state.isLoading) {
    content.push(<MoreButton />);
  }

  return <Fragment>{content}</Fragment>;
}

If anyone’s interested, here’s a written example of the unusual output.

Before clicking the MORE button, my output would look something like this.

  • item 1
  • item 2
  • item 3
  • item 4
  • MoreButton

After clicking the MORE button, the MORE button disappears (replaced with a loading animation). After loading is complete, the button returns, but output looks like this.

  • item 6
  • item 7
  • item 8
  • MoreButton
  • item 1
  • item 2
  • item 3
  • item 4
  • item 5

To me it looks to me like the last item (MoreButton) was replaced by item 5, then everything else got pushed on to the front. I did try adding keys in case that was related, but it was not.

If I put a console.log inside my makeFeedItem function, OR view the VDOM in the Preact Dev Tools, the output is what you’d expect:

  • item 1
  • item 2
  • item 3
  • item 4
  • item 5
  • item 6
  • item 7
  • item 8
  • MoreButton

Firefox and Preact 10.11.0.

2reactions
olliekavcommented, Jan 5, 2021

So the only way I could get the order to reliably work in my case, was to wrap the provider {props.children} in an extra container.

return (
    <PlayerContext.Provider value={{
      player,
      wavesurfer,
      changeVolume: changeVolume,
      playTrackAtIndex: playTrackAtIndex,
      playPause: playPause,
      setTimers: setTimers,
      initWavesurfer: initWavesurfer
    }}>
      <div class="wrapper loaded">
        <main class="main">
          {props.children}
        </main>
        <Player />
      </div>
    </PlayerContext.Provider>
  );

I’ll put together a codepen this week and see if I can replicate with a minimal use case 👍

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to randomly re-render the DOM nodes' order of ...
There are several ways you can go about "shuffling" an array. I chose the Fisher-Yates method in an experimental "war" card game.
Read more >
Randomizing the display order of content using JavaScript
Using JavaScript, we can jiggle things up, and display pieces of content that randomly interchange order.
Read more >
The 10 Most Common JavaScript Issues Developers Face
If you need help figuring out why your JavaScript isn't working, consult this list of the 10 most common JavaScript issues from a...
Read more >
eq | Cypress Documentation
Get A DOM element at a specific index in an array of elements. The querying behavior of this command matches exactly how .eq()...
Read more >
How can you randomize the order in which components are ...
If I have a few Card.js components rendered on the DOM, how can I ... it continually determines the next element by randomly...
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