react icon indicating copy to clipboard operation
react copied to clipboard

VerticalDivider for PageLayout.Pane always initially renders as style 'none'

Open Bestra opened this issue 2 years ago • 3 comments

Description

I'm using React Router to render several different pages that are laid out almost identically. They generally look like this:

<PageLayout>
  <PageLayout.Pane divider="line">
    {someContent}
  </PageLayout.Pane>
</PageLayout>

Each route renders a component with the same PageLayout.pane with a 'line' divider. When I switch routes, most of the DOM appears stable to my eyes, but there's a brief period where the vertical divider seems to disappear.

I investigated and found that this happens on initial render, and that I could recreate it via the storybook locally. In the video below I've set a breakpoint when the VerticalDivider renders. You'll see that in the first few renders, the divider doesn't show at all. On the third render it pops into view as a line the way I'd expect.

https://github.com/primer/react/assets/2043348/eaffd9e6-7027-4fc0-a4b6-6f5b38af4800

From the React devtools profiler , the VerticalDivider renders a total of 4 times. On the third render it finally becomes visible.

The react devtools profiler. The `VerticalDivider` component's third render of 4 is selected. 'Why did this render?' says 'Hooks 5 and 8 changed'

I set a logpoint in the PageLayout.Pane component to record its props over its renders. You'll see the responsiveVariant value changes from none to line. Each logpoint shows up twice since we're in strict mode.

console.log results. There are 6 lines. variant: {narrow: 'none', narrow: 'line'} is present on every line. responsiveValue is none on the first 4 lines, but line on the last 2. sx: {marginLeft: 0} is present on every line

This corresponds to the useMedia() hooks used by useResponsiveValue() going from false to true.

The hooks tab from the react devtools component window. Hooks 5 and 8 are highlighted as true. The functions for these hooks are the state of theisRegularViewport and isWideViewport from useResponsiveValue

Under the hood useResponsiveValue() calls useMedia() with a defaultState value of false for all three viewport widths https://github.com/primer/react/blob/1fd6d326fc9936428e9485e4f41f2328d8b22684/src/hooks/useResponsiveValue.ts#L52-L54

and this basically forces us to return the fallback value on initial render, which is none for the VerticalDivider.

If I modify useResponsiveValue so that it doesn't pass a default, like this:

  const isNarrowViewport = useMedia(viewportRanges.narrow)
  const isRegularViewport = useMedia(viewportRanges.regular)
  const isWideViewport = useMedia(viewportRanges.wide)

The component initially renders as I'd expect. Would a change like this be possible or will it create problems for SSR? I see this comment: https://github.com/primer/react/blob/1fd6d326fc9936428e9485e4f41f2328d8b22684/src/hooks/useMedia.tsx#L25-L28

Steps to reproduce

  1. Open the storybook and navigate to /?path=/story/components-pagelayout--default
  2. Set your Pane.divider.regular to be line storybook props for `Pane.divider.regular`, the value is set to `line`
  3. Remount the component by clicking the button on the top left The button on the top left of the storybook window. It shows two arrows flowing in a circle.

Version

v35.25.1

Browser

Chrome

Bestra avatar May 26 '23 11:05 Bestra

Hi @lesliecdubs @Bestra , can you please assign this bug to me .

amrinder1189 avatar May 30 '23 09:05 amrinder1189

@amrinder1189 thanks for offering to contribute! I'll assign to you. Let us know if you have questions while you work on this.

lesliecdubs avatar May 30 '23 17:05 lesliecdubs

Hi! This issue has been marked as stale because it has been open with no activity for 180 days. You can comment on the issue or remove the stale label to keep it open. If you do nothing, this issue will be closed in 7 days.

github-actions[bot] avatar Nov 26 '23 18:11 github-actions[bot]

Hi! This issue has been marked as stale because it has been open with no activity for 180 days. You can comment on the issue or remove the stale label to keep it open. If you do nothing, this issue will be closed in 7 days.

github-actions[bot] avatar May 25 '24 15:05 github-actions[bot]