Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react.js - React-router dealing with fixed headers and footers

I have React.js app flavored with react-router, I have a doubt regarding my current routes handling.

Design looks as follows, common mobile layout, fixed header and footer, content in the middle:

enter image description here

In the case they are static I can simply create such structure:

<RatchetHeader />
<RatchetFooter />
<RouteHandler />

But occasionally they would change from page to page, for example:

  • title and button texts
  • number of buttons
  • footer is not present on some pages

Is it better to put them inside view controllers and re-render everytime with RouteHandler?

like image 249
Kosmetika Avatar asked Jan 21 '15 21:01

Kosmetika


1 Answers

I don't know specifics of Ratchet, but in general terms of react, in your situation, it's better indeed for the footer to put it inside a RouteHandler, so that you can define its presence depending on your preferences.

For the Header, I believe you'd always like to have it there? In that case, you could leave it outside the Handler and pass it properties instead to change it's layout.

The final result would look something similar to this (the component imports are implied, therefore I'm not including them for the sake of keeping focus on the logic):

The app.js:

<Route handler={AppHandler}>
  <DefaultRoute handler={HomeHandler}/>
  <Route name='foo' path='/foo' handler={FooHandler}/>
  <Route name='bar' path='/bar' handler={BarHandler}/>
  <NotFoundRoute handler={NotFoundHandler}/>
</Route>

);

The App.react.js:

<div>
  <Header title={this.state.title}/>
  <RouteHandler {...this.props}/>
</div>

The Header.react.js - using some imaginary components for illustration:

var Header = React.createClass({
  render: function(){
    return (
      <div>
        <Button type="previous" title="Left"/>
        <HeaderTitle>{this.props.title}</HeaderTitle>
        <Button type="next" title="Right"/>
      </div>
    );
  }
});

module.exports = Header;

The Foo.react.js:

var Foo = React.createClass({
  render: function(){
    var footerActions = [ // Ideally you'd get this from a constants file or something alike.
      {
        'actionType': 'viewHome',
        'actionIcon': 'icon-home',
        'actionLabel': 'Home'
      },
      {
        'actionType': 'viewProfile',
        'actionIcon': 'icon-profile',
        'actionLabel': 'Profile'
      },
      {
        'actionType': 'viewFavorites',
        'actionIcon': 'icon-favorites',
        'actionLabel': 'Favorites'
      },
      ...
    ];
    return (
      <div>Your content here</div>
      <Footer actions={footerActions}/>
    );
  }
});

module.exports = Foo;

The Footer.react.js:

var Footer = React.createClass({
  render: function(){
    var actionItems = this.props.actions.map(function(item){
      return (<ActionItem action={item.actionType} icon={item.actionIcon} label={item.actionLabel}/>);
    });
    return (
      <div>{actionItems}</div>
    )
  }
});

module.exports = Footer;

Then, in the Bar.react.js you could just not include the <Footer> component, like this:

The Bar.react.js:

var Bar = React.createClass({
  render: function(){
    return (
      <div>Your content here</div>
    );
  }
});

module.exports = Bar;

Hope that helps!

like image 89
Alexandre Theodoro Avatar answered Oct 22 '22 20:10

Alexandre Theodoro