Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React set state/props on route using react router

I am somewhat new to React. so please bear with me. I have the following base structure:

<App>
 this.props.children
</App>

...and in children, one component is a header that has what I want to be an optional search component:

<Header>
  ...some other children...
  <Search /> <- STUCK HERE SHOULD BE OPTIONAL!!!
</Header>
 ...children from other components...

What I am trying to do is say when I go to route A, the search component should not be included (or at least not shown), but when I go to route B, it should. I have scoured for days and so far been unable to find a solution that meets this need. If it matter, I am using ES6/7 (babel via webpack).

I can set state in the APP and toggle it literally to adjust the passed down props on the Search and show or not show it, but cannot figure out how to do that dynamically based on the route.

The core issue is how to tell App (and indirectly Header) to show the search component on inside the Header on some routes, but not on others. I 'think' maybe I need some sort of abstraction/wrapper component in the middle, but am not really sure. Any though or ideas are welcome.

TIA!

like image 922
D Durham Avatar asked Mar 15 '23 01:03

D Durham


1 Answers

First setup your routes.

<Router path="/" component={App}>
  <Route path="foo" component={Header} showSearch={true} />
  <Route path="bar" component={Header} showSearch={false} />
</Router>

The route will be passed down as a property, then you can access the showSearch property, which determines whether the search component is rendered.

// Header
render() {
  const { showSearch } = this.props.route;

  return (
    <div className='header'>
      // ... other components
      { showSearch ? <Search /> : null }
    </div>
  );
}

Maybe you don't want your header to be the top level component though. In that case define an intermediary wrapper component that forwards the route props down to the header.

<Router path="/" component={App}>
  <Route path="foo" component={Shell} showSearch={true} />
  <Route path="bar" component={Shell} showSearch={false} />
</Router>

// Shell
render() {
  const { route } = this.props;
  return (
    <div className='shell'>
      <Header {...route} />
    </div>
  );
}

Alternatively, you could do a quick and dirty check from inside your Header component.

// Header
render() {
  const { hash } = window.location,
        showSearch = /\/foo/.test(hash);

  return (
    <div className='header'>
      // ... other components
      { showSearch ? <Search /> : null }
    </div>
  );
}
like image 120
Dan Prince Avatar answered Mar 23 '23 15:03

Dan Prince