lightweight
lightweight

Reputation: 3327

reactjs sidebar with react-router

I'm new to react and have been trying to find an example of how to create a side nav bar in reactjs and use reactrouter with with it. Right now, I have a "side nav" pane that looks like this:

import React, {PropTypes} from 'react';
import { Link, IndexLink } from 'react-router';

const Header = () => {
    return (
        <nav>
            <div>
                <ul>
                    <li>
                        <IndexLink to="/" activeClassName="active">Home</IndexLink>
                    </li>
                    <li>
                        <Link to="/courses" activeClassName="active">Courses</Link>
                    </li>
                    <li>
                        <Link to="/about" activeClassName="active">About</Link>
                    </li>
                </ul>
            </div>
        </nav>
    );
};

export default Header;

but I want to turn that into a side nav bar but can't seem to find anything online with an example on how to do that.

-------EDIT--------

So I tried this, but still no luck...

app.js looks like this:

// This component handles the App template used on every page.
import React, {PropTypes} from 'react';
import SideBar from './common/Header';

class App extends React.Component {
    render() {
        return (
            <div className="container-fluid">
                        <SideBar />
                        {this.props.children}
            </div>
        );
    }
}

App.propTypes = {
    children: PropTypes.object.isRequired
};

export default App;

SideBar component:

import React, {PropTypes} from 'react';
import { Link, IndexLink } from 'react-router';

const SideBar = () => {
    return (
        <nav>
            <div>
                <ul>
                    <li>
                        <IndexLink to="/" activeClassName="active">Home</IndexLink>
                    </li>
                    <li>
                        <Link to="/courses" activeClassName="active">Courses</Link>
                    </li>
                    <li>
                        <Link to="/about" activeClassName="active">About</Link>
                    </li>
                </ul>
            </div>
        </nav>
    );
};

export default SideBar;

style.css looks like this:

#app {
    font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
    color: #4d4d4d;
    min-width: 550px;
    max-width: 850px;
    margin: 0 auto;
}

a.active {
    color: orange;
}

nav {
    padding-top: 20px;
    padding-bottom: 20px;
}

.container {
    display: flex;

    > * { height: 100%; }

    .sidebar {
        width: 250px;
    }

    .content {
        width: 100%;
    }
}

Upvotes: 4

Views: 6313

Answers (1)

Tyler Sebastian
Tyler Sebastian

Reputation: 9448

This is more a CSS problem than a React problem - anything can be made a sidebar with the right CSS. That said, there's a good way to set this up in React as well, so I'll show you that.

I would suggest having the following, or something close.

The router would be structured in the following way:

<Route path="/" component={WrapperComponent}/>
    <Route path="/somepath" component={SomeComponent}/>
    ...
</Route>

WrapperComponent would look like

class WrapperComponent extends React.Component {
    render() {
        return (
            <div>
                <SideBar props... />
                { this.props.children }
            </div>
        )
    }
}

Your SideBar class would look more or less like what you have above (but renamed, because it matters ;))

This would automatically place the current view inside WrapperComponent where { this.props.children } is, beside the sidebar (assuming you have your styling correctly set up). In this example, navigating to /something would result in a split layout with your sidebar on the left and SomeComponent being rendered on the right.

For styles, something like

.container {
    display: flex;
}

.container > * { height: 100%; }

.container .sidebar {
    width: 250px;
}

.container .content {
    width: 100%;
}

would get you close.

edit there are a couple things wrong with the code you're using - even if you copy/paste my updated styles:

  1. you're using .container-fluid instead of .container, which my styles use. If you're using Bootstrap, instead of display: flex, just use bootstrap columns (i.e. col-md-3 on the sidebar and col-md-9 on the content) - or avoid Bootstrap collisions by using something other than .container(-fluid) for the container name.
  2. SideBar needs a className (.sidebar) if you want the styles to apply. SideBar is just the component class and does no effect on the HTML classnames. You can change .sidebar to nav, if that's easier for you.
  3. either wrap { this.props.children } in something with .content as a class or make sure whatever is being rendered there has that class. This could be accomplished by accepting a className prop to potential elements.
  4. making something is fun - but you need to understand what you're doing as well. Just copy/pasting something from here into your codebase without first understanding what it means/what it's doing is wasting your time (imo).

Upvotes: 3

Related Questions