bvaughn / react-resizable-panels

https://react-resizable-panels.vercel.app/
MIT License
3.69k stars 130 forks source link

Dynamically adding panels in child component throws `Previous layout not found for panel index` #372

Closed davidfant closed 2 weeks ago

davidfant commented 4 weeks ago

I'm running into problems with defining panels within a child component and dynamically adding children. When trying to resize, the following error is console logged and the panel sizes don't change: Previous layout not found for panel index

Example:

const ChildWithDynamicPanels = () => {
  const [extra, setExtra] = useState(2);
  return (
    <>
      {Array.from({ length: extra }).map((_, i) => (
        <Fragment key={i}>
          <PanelResizeHandle />
          <Panel id={`extra-${i}`} order={i}>
            <div style={{ width: "100%", background: "red" }}>{i}</div>
          </Panel>
        </Fragment>
      ))}
      <button onClick={() => setExtra((e) => e + 1)}>Add</button>
    </>
  );
};

export function Parent({
  panels,
  children,
}: ResizablePanelsProps) {
  return (
    <PanelGroup      direction="horizontal"    >
      <ChildWithDynamicPanels />
    </PanelGroup>
  );
}

Behavior I'm seeing in the reproable example above:

  1. Dragging the first two children works because they were defined on the initial render
  2. When adding a new child, the first drag creates lots of errors and resets all sizes to be equal. Subsequent resizing works.
  3. If everything in ChildWithDynamicPanels is moved into Parent, then there's no error. However, when adding a new panel, the resizing is reset and each panel gets the same size (unlike point 2 where the reset doesn't happen until dragging is attempted)

The reason I need this is because I'm using NextJS App Router, where depending on the current route additional panels might be rendered based on the route. This means that these Panels will be within a separate page.tsx file and thus not rendered as a direct child to the panel group. If there's a better way to do this for the NextJS App Router scenario, please let me know!

bvaughn commented 3 weeks ago

@davidfant Can you please share a runnable repro of the problem you're reporting?

The code snippet you shared doesn't really make sense. (The props passed to Parent aren't even use.) But more than that, it's better if I can just click a link and start looking at the problem rather than spending time trying to re-create it.

davidfant commented 3 weeks ago

@bvaughn here you go: https://github.com/davidfant/react-resizable-panels-issue-372/blob/master/src/components/Example1.tsx

Run yarn dev and go to localhost:3000

bvaughn commented 3 weeks ago

Thanks. I can see the error now. Made it into a Sandbox here and recorded a Replay here.

bvaughn commented 2 weeks ago

Okay I think I see the problem here.

bvaughn commented 2 weeks ago

Fix published in version 2.0.22


❤️ → ☕ givebrian.coffee