#NavLink Tree not rendering children on data update

45 messages ยท Page 1 of 1 (latest)

jovial plume
#

I have a tree-view build out of NavLinks. I've implemented both selection and open/close. It gets rendered recursively from a nested JSON source. Everything works fine.

I added a button to append new items to the tree. It recursively rebuilds the data tree and checks if the "path" where it is at matches the "path" that's currently selected, and returns a new array of child elements with the new element at the end. This also works fine.

The problem is that when I call setJsonData (from the state hook) on this rebuilt tree, the NavLink components don't show the new items. But if I "close" the right one and then "open" it again, the item shows up correctly.

Additionally, adding a new item closes other parts of the NavLink tree for whatever reason.

Both the JSON objects and the NavLinks have UUID keys, I have no idea what I'm doing wrong. This feels like I'm not managing my state updates properly but I'm quite new to Javascript and even more so to React so I really need some help.

EDIT: it works as long as the subtree has at least one child element, it's only when going from 0 to more than 0 that it does not update without opening and closing first...

spice patio
#

^ try to keep this out of #๐Ÿ’ญ-feedback and in #1006447791498870784, feedback is for mantine library feedback only

#

anyway, your problem looks like lack of keys

jovial plume
#

you can add keys to the example (my original code has them)

#

it'll still break

#

with unique keys:

import { Button, NavLink } from '@mantine/core'
import { useState } from 'react'
import { v4 as uuidv4 } from 'uuid'

interface JsonData {
  key: string;
  label: string;
  children: JsonData[];
}

const initialData : JsonData[] = [{key: uuidv4(), label: 'parent', children: []}]

function Tree(props: {data: JsonData}) {
  return (
    <NavLink key={props.data.key} label={props.data.label} childrenOffset="lg">
      {props.data.children.map((item) => <Tree data={item}></Tree>)}
    </NavLink>
  );
}

function update(old: JsonData[]): JsonData[] {
  return old.map((item) => (
    {...item, children: [...item.children, {key: uuidv4(), label: 'child', children: []}]}
  ));
}

function App() {
  const [data, setData] = useState(initialData);
  return (
    <>
      <Button onClick={() => setData((old) => update(old))}>Add Child</Button>
      {data.map((item) => <Tree data={item}></Tree>)}
    </>
  );
}
spice patio
#

these two do not have keys, although update() might not need them

#

yeah i guess update() won't need them

#

make sure the render in App() gets them

jovial plume
#

I'll try adding a key to Tree to see if it makes a difference

#

give me a sec

spice patio
jovial plume
#

thankyou for making a sandbox!

#

(I don't have an account there)

#

the bug seems to be present there too

spice patio
#

keys are super important - the moment you use .map(), you should always use key. also, try to force the keys to be as unique as possible (for example the second arg from map, index, isn't always the best in cases where you delete items in the middle of the array

#

what bug are you experiencing, the collapsing issue is not occurring for me

jovial plume
#
  • refresh page
  • open parent
  • click add child a bunch of times
  • nothing happens <-- bug
  • close parent
  • open parent
  • all child elements are there
#

this in safari

#

I'll test in firefox and chrome, give me a sec

#

also happens in firefox

#

chrome too, at least behavior seems to be consistent across browsers

#

let me see if I can record a video

spice patio
#

i see what you're referring to

jovial plume
#

a recording in case it helps someone else see the issue

cerulean wasp
jovial plume
#

I'll try to update as soon as I'm home, I'll report afterwards

cerulean wasp
jovial plume
#

@cerulean wasp remove the 2 items, close and reopen the tree, then press Add Item again

#

it's still broken

#

EDIT: proper video

#

it only triggers in the transition from 0 elements to more than 0 elements

#

updating packages didn't seem to have any effect locally

cerulean wasp
jovial plume
#

oh wow, that works!

#

would you mind explaining why it makes a difference?

#

I'm very new to react/javascript coding

#

(long term programmer, just new to frontend)

cerulean wasp
jovial plume
#

well, I'll take it! thanks for helping out! mantine is by far my favorite react component library and this was a pretty big showstopper for the app I'm building ๐Ÿ˜„

spice patio
spice patio