Search code examples
reactjsreact-routerreact-reduxbrowser-history

React: how to keep sidepanel state between url changes with history.push()?


I have a fixed sidepanel that contains a search bar with filter buttons similar to https://facebook.github.io/react/docs/thinking-in-react.html

The list items are clickable and trigger history.push() for nested path urls.

The nested path structure is

/category-1
/category-1/product-1
/category-1/product-2
/category-2
/category-2/product-1
/category-2/product-2
 .
 .
 .
/category-n/product-m
/category-n/product-k

User can scroll the sidepanel's list and select filters. However, a click on a list item (with onClick() followed by history.push()) causes the whole page (including the sidepanel) to render. This in turn doesn't keep the sidepanel's state so the filters and the scroll position are reset.

The parent render: function() looks like:

return(
  <div id="main-view">
    <Sidepanel history={this.props.history} properties={this.props.properties} />
    React.cloneElement(this.props.children, {this.props});
  </div>
);

The React.cloneElement() is the product info container that should render only.

I'm using react-router, react-redux and redux-simple-router.

Do I need to store the sidepanel's list scroll position and filter values outside of the sidepanel? Or is there a better way to keep the sidepanel's state between the url changes?


Solution

  • Your architecture is not aligned with what you want to do.

    Simply render the navigation in your top-level, parent component and it will never lose state - for example in your Application component. Then SidePanel wouldn't be affected by route change.

    Also you could pass down a callback to set / alter navigation from children, if needed (for example hide() or addMenuItems()).