#Help understanding reactivity

39 messages · Page 1 of 1 (latest)

stoic trail
#

I have a component, child-component pair.

However, when I try to move some of this logic to a hook, the parent rerenders, but the child does not. The props passed to the children change, so why doesn't the child ge rerendered??

Console Logs

// first render, data not loaded from local storage yet, etc
CanvasBusDebug.tsx:36 Rendering canvas bus debug
CanvasBusDebug.tsx:15 Calculating root data
CanvasBusDebug.tsx:19 Metadata: []
CanvasBusDebug.tsx:39 Root items: []
CanvasHierarchySection.tsx:15 Rendering canvas hierarchy section <--- child gets rendered
CanvasHierarchySection.tsx:16 root items []

// data gets loaded, now there are metadatas
// however CanvasHierarchySection is never rendered again

CanvasBusDebug.tsx:36 Rendering canvas bus debug
CanvasBusDebug.tsx:15 Calculating root data
CanvasBusDebug.tsx:19 Metadata: (2) [{…}, {…}]
CanvasBusDebug.tsx:28 [CanvasBusDebug] Sorting punctual-1761808294591-canvaspunctual-1761808294591 vs punctual-1761808355949-canvaspunctual-1761808355949 = 0
CanvasBusDebug.tsx:39 Root items: (2) [{…}, {…}]
<--- CanvasHierarchySection never rendered again!

This version with no hook works: https://gist.github.com/dustinlacewell/4173e4b4ac5619fa1acbc53979b605d3
This version where I move some of the logic to a hook, causes the child to stop rendering as shown above: https://gist.github.com/dustinlacewell/e9e09898fa3fbd89f7f8b0de156ad890

I am just looking for some help trying to understand specifically why in the broken version the child component never gets rendered again

stoic trail
#

Basically, I tried to move some of the component's state management to a helper hook, for decomposition's sake -- but when I do that, that component's child never renders again. I expect to see the CanvasHierarchySection re-render any time its props change.

#
<CanvasBusDebug>
  const rootItems = // calculate it right here
  <CanvasHierarchySection rootItems={rootItems} />
</CanvasBusDebug>

vs

<CanvasBusDebug>
  const { rootItems } = useCalculateRootData()
  <CanvasHierarchySection rootItems={rootItems} />
</CanvasBusDebug>
#

@lime cape

#

Where useCalculateRootData() looks like:

const useCalculateRootData = () => {
  console.log("Calculating root data");
  const canvasBus = useCanvasBus();
  const layout = useLayout();
  const metadata = Array.from(canvasBus.canvasMetadata.value.values());
  console.log("Metadata:", metadata);
  const rootItems = metadata
    .sort((a, b) => {
      // Get position in layout order (which determines z-index)
      const indexA = layout.instanceOrder.indexOf(a.instanceId);
      const indexB = layout.instanceOrder.indexOf(b.instanceId);
      return indexB - indexA; // Descending: higher index (higher z) first, lower index (lower z) last
    });

  return rootItems
}
lime cape
#

so

<CanvasBusDebug>
  const rootItems = // calculate it right here
  <CanvasHierarchySection rootItems={rootItems} />
</CanvasBusDebug>

works?

stoic trail
#

yeah, the child gets rerendered as expected

#

in the broken version, the child is just the SSG (no state) version and never updates

#

even though the same data is changing, etc, the parent gets rerendered when the data changes, etc

#

I can obviously move this root data calculation to a normal function and pass the canvasbus, layout in as params, then it works, but I am trying to understand why I failed to make this hook

#

I tried that and it works, which makes sense, a normal function is transparently equivalent to having the code at the callsite

#

@lime cape you know what I will try to make a tiny reproducable case and if I can't, I wont mention it again 😄

lime cape
#

haha that's what I was going to suggest

#

hard to track with so much going on

stoic trail
#

lol

stoic trail
#

🤣

#

oh interesting the js fails to load

lime cape
#

are the buttons supposed to do something? 😅

stoic trail
#

Failed to load resource: the server responded with a status of 404 ()Understand this error
build/q-BAMLJNcO.js:1 Failed to load resource: the server responded with a status of 404 ()Understand this error
build/q-naDMFAHy.js:1 Failed to load resource: the server responded with a status of 404 ()Understand this error
build/q-BKuJGWh-.js:1 Failed to load resource: the server responded with a status of 404 ()Understand this error
2qwik-hook-test/:1 Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: https://ldlework.com/build/q-BAMLJNcO.js

lime cape
#

ah right

stoic trail
#

I guess because github tries to serve all my pages under the same domain?

#

or something

#

just run it I guess if you have time

#

i tried 😭

#

lol

lime cape
#

so that's the most minimal you can get it to fail?

stoic trail
#

well you can remove the layout bit from the context since it's not actually used

#

but i feared going any further would not resemble what i'm doing in my actual code

#

what's nuts if you can try to follow along

#

i fix the broken version by simply renaming the "hook" from useComputeDataBroken -> computeDataBroken

#

this has me baffled

#

you can mostly ignore the add/remove etc, they are just there so there's some interactivity

#

the main part is calculating the root data that's passed to the child

lime cape
#

I'm a bit short on time atm

#

this might be a bug