Permalink
Browse files

Adding a NavBar

  • Loading branch information...
1 parent 29a099f commit 1e08f686a2c127b356ef0ad5b1cdcb21fc9a700f @alexishevia committed Nov 27, 2014
Showing with 81 additions and 9 deletions.
  1. +11 −3 README.md
  2. +2 −0 components/Application.jsx
  3. +20 −0 components/HTML.jsx
  4. +38 −0 components/Nav.jsx
  5. +4 −2 configs/routes.js
  6. +6 −4 server.js
View
@@ -8,8 +8,8 @@ On this post I want to show how to create a fluxible app step by step. I will be
- create an express app (server.js). Add a middleware to render our React component.
## Using routes
-- Create <Home> and <About> Components
-- Modify the ApplicationComponent so it renders either <Home> or <About> based on the current route.
+- Create `<Home>` and `<About>` Components
+- Modify the ApplicationComponent so it renders either `<Home>` or `<About>` based on the current route.
- Create app.js, our Fluxible-app. app.js uses a routrPlugin (with our custom defined routes), and an ApplicationStore, which holds the current route as its state.
- Modify server.js so it creates a new context on each request, and executes the NavigateAction before rendering.
@@ -24,6 +24,14 @@ Note: A new ApplicationStore instance is created, and the action is immediately
5. ApplicationStore executes its handleNavigate() method in response to the 'CHANGE_ROUTE_SUCCESS' action. The handleNavigate() method will update the ApplicationStore state.
6. Inside the executeAction callback, we'll create a new instance of our Application component, passing it the current context as a prop. The context, among other things, contains the ApplicationStore instance that was created on step 4.
7. We render the Application component as a string, and send the result as our response.
-Since the Application component gets its state from ApplicationStore, and ApplicationStore was updated when it handled the 'CHANGE_ROUTE_SUCCESS', we can use the current state to determine which sub-component to render (<Home> or <About>)
+Since the Application component gets its state from ApplicationStore, and ApplicationStore was updated when it handled the 'CHANGE_ROUTE_SUCCESS', we can use the current state to determine which sub-component to render (`<Home>` or `<About>`)
Note: We're using the FluxibleMixin, which includes a handy `getStore()` method that knows how to get the correct store instance from the provided context.
+
+## Adding a NavBar
+- Create `<Nav>` component, to render our nav bar.
+- Modify `<Application>`, so it renders `<Nav>` above the content
+- Add a 'label' property to our urls, so we can use it inside `<Nav>`
+// To get styling
+- Create an `<HTML>` component, to render the base template for our app (including styles)
+- Modify server.js so it renders the app component inside the html component
@@ -3,6 +3,7 @@ var React = require('react');
var ApplicationStore = require('../stores/ApplicationStore');
var Home = require('./Home.jsx');
var About = require('./About.jsx');
+var Nav = require('./Nav.jsx');
var FluxibleMixin = require('fluxible').Mixin;
var Application = React.createClass({
@@ -13,6 +14,7 @@ var Application = React.createClass({
render: function(){
return (
<div>
+ <Nav selected={this.state.currentPageName} links={this.state.pages} context={this.props.context}/>
{'home' === this.state.currentPageName ? <Home/> : <About/>}
</div>
);
View
@@ -0,0 +1,20 @@
+'use strict';
+var React = require('react');
+
+module.exports = React.createClass({
+ render: function() {
+ return (
+ <html>
+ <head>
+ <meta charSet="utf-8" />
+ <title>{this.props.title}</title>
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.5.0/pure-min.css" />
+ </head>
+ <body>
+ <div id="app" dangerouslySetInnerHTML={{__html: this.props.markup}}></div>
+ </body>
+ </html>
+ );
+ }
+});
View
@@ -0,0 +1,38 @@
+'use strict';
+var React = require('react');
+var NavLink = require('flux-router-component').NavLink;
+
+var Nav = React.createClass({
+ getInitialState: function () {
+ return {
+ selected: 'home',
+ links: {}
+ };
+ },
+ render: function() {
+ var selected = this.props.selected || this.state.selected,
+ links = this.props.links || this.state.links,
+ context = this.props.context,
+ linkHTML = Object.keys(links).map(function (name) {
+ var className = '',
+ link = links[name];
+ if (selected === name) {
+ className = 'pure-menu-selected';
+ }
+ return (
+ <li className={className} key={link.path}>
+ <NavLink href={link.path} routeName={link.page} context={context}>
+ {link.label}
+ </NavLink>
+ </li>
+ );
+ });
+ return (
+ <ul className="pure-menu pure-menu-open pure-menu-horizontal">
+ {linkHTML}
+ </ul>
+ );
+ }
+});
+
+module.exports = Nav;
View
@@ -2,11 +2,13 @@ module.exports = {
home: {
path: '/',
method: 'get',
- page: 'home'
+ page: 'home',
+ label: 'Home'
},
about: {
path: '/about',
method: 'get',
- page: 'about'
+ page: 'about',
+ label: 'About'
}
};
View
@@ -6,6 +6,7 @@ var port = process.env.PORT || 3000;
var navigateAction = require('flux-router-component').navigateAction;
var React = require('react');
var app = require('./app');
+var HtmlComponent = React.createFactory(require('./components/HTML.jsx'));
server.use(function(req, res, next) {
var context = app.createContext();
@@ -23,10 +24,11 @@ server.use(function(req, res, next) {
}
var AppComponent = app.getAppComponent();
- var component = AppComponent({
- context: context.getComponentContext()
- });
- var html = React.renderToString(component);
+ var html = React.renderToStaticMarkup(HtmlComponent({
+ markup: React.renderToString(AppComponent({
+ context: context.getComponentContext()
+ }))
+ }));
res.send(html);
});

0 comments on commit 1e08f68

Please sign in to comment.