I've got a component, Split, which takes two children. The first child will be displayed on the left hand side of the screen & the second child on the right hand side. If the screen width goes below a certain point then only the right side will be displayed and the left side will be removed from the DOM.
Example children could be a Sidebar component and a Content component. For mobile devices i don't want to display the menu, but have a special mobile menu that i pop up.
My question is: How can i remove the Sidebar component without unmounting & remounting the Content component too?
My Content component fetches data on componentDidMount and i don't want it to refetch or re-mount(thus discarding user input) again.
Basically i have something like this:
<Split>
  <Sidebar/>
  <Content/>
</Split>
And Split's render method looks something like this:
let children;
let firstChild = this.props.children[0];
let lastChild = this.props.children.pop();
if (this.state.responsive === 'singleColumn') {
  children = (
    <div>
      <div style={{display: 'none'}}>{firstChild}</div>
      {lastChild}
    </div>
  );
} else {
  children = (
    <div>
      {firstChild}
      {lastChild}
    </div>
  );
}
return (
  <div>
    {children}
  </div>
);
Even though {lastChild} is always rendered, no matter what, it still gets unmounted and remounted each time split has to re-render!
Even having a render that looks like this:
return (
  <div>
    {this.props.children.pop()}
  </div>
);
causes the last child(which never changes) to be unmounted & remounted before being rendered.
If i instead modify Split and pass the component that will always be in the DOM as an attribute like so:
<Split staticComponent={<Content />}>
  <Sidebar />
</Split>
it works fine. Then why doesn't it work when im just popping the last child like this {this.props.children.pop()} as opposed to this {this.props.staticComponent}
Is there a sane way to solve this?
Finally managed to solve the issue! I re-wrote Split's render to look something like this:
let left;
if (this.state.responsive !== 'singleColumn') {
  left = this.props.children.slice(0, -1);
}
return (
  <div ref="split" className={classes.join(' ')}>
    {left}
    {this.props.children[this.props.children.length-1]}
  </div>
);
This way the last child always gets rendered. Obviously pop() didn't work because then i modified the original array of children which triggered the weird behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With