zesik / react-splitter-layout

A simple split layout for React and modern browsers. https://zesik.com/react-splitter-layout
MIT License
422 stars 128 forks source link

React components re-render when splitter layout changes #43

Open arifsuleman opened 4 years ago

arifsuleman commented 4 years ago

Hi, I have single reactjs web page where I have implemented splitter. I have two layouts for splitter like horizontal and vertical with showing same set of reactjs components. My problem is : my reactjs components re-render when user changes splitter from vertical to horizontal or vice versa. Because of re-rendering on splitter changes, user losing entered information on all input fields. Is there a way to persist user entered information on input fields during splitter layout is changed? thanks Arif

zesik commented 4 years ago

Hi, are you storing the entered information somewhere in the state?

hshelbur commented 4 years ago

I have a similar issue, but it isn't data being lost. I have an expensive to render component in a right panel that is being re-rendered whenever the left panel is open/closed. Any suggestions on how to possibly avoid this?

sebastianfrey commented 4 years ago

@hshelbur react-splitter-layout uses conditional rendering with boolean short-circuiting as API to hide the secondary pane.

<SplitterLayout>
   <PrimaryPaneContent />
   {secondaryPaneVisible && <SecondaryPaneContent>}
<SplitterLayout />

While this aproach seems to be smart, it creates DOM-Elements every time the second pane is displayed. In other words, a complete re-render.

But there is a solution. You can do something like this, to keep a component mounted, when you want to hide it conditionally:

<div style={{ display: condition ? '' : 'none' }}>
  <Content  />
</div>

The <SplitterLayout> component may implement a new API in the future to hide the secondary pane, which leverages the above aproach. A possible implementation might be a new property like secondaryHidden to hide the secondary pane conditionally.

<SplitterLayout secondaryHidden={secondaryPaneVisible}>
   <PrimaryPaneContent />
   <SecondaryPaneContent>
<SplitterLayout />

But this would be a breaking change, but maybe the library can support both ways in the future to hide the secondary pane?

@zesik Any thoughts on that?

kegi commented 3 years ago

An alternative in sass I'm using to avoid re-rendering:

<SplitterLayout customClassName={`${openSideBar || 'splitter-layout-secondary-panel-hidden'}`}>
...
</SplitterLayout>
.splitter-layout-secondary-panel-hidden {
  & > .layout-pane {
    width: 0 !important;
    .layout-pane-primary {
      width: 100% !important;
    }
  }
  & > .layout-splitter {
    display: none;
  }
}