Commit b9fec275b25f98781d4660df14367ab6e0246391

Authored by tmcdeveloper
1 parent 36a4c235df
Exists in master

add fix for active state bug

- Fixes issue where the active state for links wasn't updating. This is due to a bug in React and this implements
a workaround which relies on setting { pure: false } on the main component container to prevent blocking re-renders
when moving between routes (and leaving the active state on the old route). Hopefully this is fixed in the future
as this isn't an ideal implementation.
imports/ui/components/app-navigation.js
1 import React from 'react'; 1 import React from 'react';
2 import { Navbar, Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap'; 2 import { Navbar, Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';
3 import { Link } from 'react-router'; 3 import { Link } from 'react-router';
4 import { PublicNavigation } from './public-navigation'; 4 import { PublicNavigation } from './public-navigation';
5 import { AuthenticatedNavigation } from './authenticated-navigation'; 5 import { AuthenticatedNavigation } from './authenticated-navigation';
6 6
7 export class AppNavigation extends React.Component { 7 export class AppNavigation extends React.Component {
8 renderNavigation( hasUser, activeRoute ) { 8 renderNavigation( hasUser ) {
9 return hasUser ? <AuthenticatedNavigation activeRoute={ activeRoute } /> : <PublicNavigation activeRoute={ activeRoute } />; 9 return hasUser ? <AuthenticatedNavigation /> : <PublicNavigation />;
10 } 10 }
11 11
12 render() { 12 render() {
13 return <Navbar> 13 return <Navbar>
14 <Navbar.Header> 14 <Navbar.Header>
15 <Navbar.Brand> 15 <Navbar.Brand>
16 <Link to="/">Application Name</Link> 16 <Link to="/">Application Name</Link>
17 </Navbar.Brand> 17 </Navbar.Brand>
18 <Navbar.Toggle /> 18 <Navbar.Toggle />
19 </Navbar.Header> 19 </Navbar.Header>
20 <Navbar.Collapse> 20 <Navbar.Collapse>
21 { this.renderNavigation( this.props.hasUser, this.props.activeRoute ) } 21 { this.renderNavigation( this.props.hasUser ) }
22 </Navbar.Collapse> 22 </Navbar.Collapse>
23 </Navbar>; 23 </Navbar>;
24 } 24 }
25 } 25 }
26 26
imports/ui/components/authenticated-navigation.js
1 import React from 'react'; 1 import React from 'react';
2 import { browserHistory, IndexLink, Link } from 'react-router'; 2 import { browserHistory } from 'react-router';
3 import { IndexLinkContainer, LinkContainer } from 'react-router-bootstrap';
3 import { Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap'; 4 import { Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';
4 5
5 const handleLogout = () => { 6 const handleLogout = () => {
6 return Meteor.logout( () => browserHistory.push( '/login' ) ); 7 return Meteor.logout( () => browserHistory.push( '/login' ) );
7 }; 8 };
8 9
9 const userName = () => { 10 const userName = () => {
10 const user = Meteor.user(); 11 const user = Meteor.user();
11 if ( user ) { 12 if ( user ) {
12 const name = user && user.profile ? user.profile.name : ''; 13 const name = user && user.profile ? user.profile.name : '';
13 return `${ name.first } ${ name.last }`; 14 return `${ name.first } ${ name.last }`;
14 } 15 }
15 }; 16 };
16 17
17 export const AuthenticatedNavigation = () => ( 18 export const AuthenticatedNavigation = () => (
18 <div> 19 <div>
19 <Nav> 20 <Nav>
20 <li><IndexLink to="/" activeClassName="active">Index</IndexLink></li> 21 <IndexLinkContainer to="/">
21 <li><Link to="/dashboard" activeClassName="active">Dashboard</Link></li> 22 <NavItem eventKey={ 1 } href="/">Index</NavItem>
23 </IndexLinkContainer>
24 <LinkContainer to="dashboard">
25 <NavItem eventKey={ 2 } href="/dashboard">Dashboard</NavItem>
26 </LinkContainer>
22 </Nav> 27 </Nav>
23 <Nav pullRight> 28 <Nav pullRight>
24 <NavDropdown eventKey={ 3 } title={ userName() } id="basic-nav-dropdown"> 29 <NavDropdown eventKey={ 3 } title={ userName() } id="basic-nav-dropdown">
25 <MenuItem eventKey={ 3.1 } onClick={ handleLogout }>Logout</MenuItem> 30 <MenuItem eventKey={ 3.1 } onClick={ handleLogout }>Logout</MenuItem>
26 </NavDropdown> 31 </NavDropdown>
27 </Nav> 32 </Nav>
28 </div> 33 </div>
29 ) 34 )
30 35
imports/ui/components/public-navigation.js
1 import React from 'react'; 1 import React from 'react';
2 import { Link } from 'react-router'; 2 import { LinkContainer } from 'react-router-bootstrap';
3 import { Nav, NavItem } from 'react-bootstrap'; 3 import { Nav, NavItem } from 'react-bootstrap';
4 4
5 export const PublicNavigation = () => ( 5 export const PublicNavigation = () => (
6 <Nav pullRight> 6 <Nav pullRight>
7 <li role="presentation"><Link to="/signup">Sign Up</Link></li> 7 <LinkContainer to="signup">
8 <li role="presentation"><Link to="/login">Log In</Link></li> 8 <NavItem eventKey={ 1 } href="/signup">Sign Up</NavItem>
9 </LinkContainer>
10 <LinkContainer to="login">
11 <NavItem eventKey={ 2 } href="/login">Log In</NavItem>
12 </LinkContainer>
9 </Nav> 13 </Nav>
10 ) 14 )
11 15
imports/ui/containers/app-navigation.js
1 import { createContainer } from 'meteor/react-meteor-data'; 1 import { composeWithTracker } from 'react-komposer';
2 import { AppNavigation } from '../components/app-navigation'; 2 import { AppNavigation } from '../components/app-navigation';
3 3
4 export default createContainer( ( { params } ) => { 4 const composer = ( props, onData ) => {
5 return { hasUser: Meteor.user() }; 5 onData( null, { hasUser: Meteor.user() } );
6 }, AppNavigation ); 6 };
7
8 export default composeWithTracker( composer, {}, {}, { pure: false } )( AppNavigation );
7 9
1 { 1 {
2 "name": "application-name", 2 "name": "application-name",
3 "version": "1.0.0", 3 "version": "1.0.0",
4 "description": "Application description.", 4 "description": "Application description.",
5 "scripts": { 5 "scripts": {
6 "start": "meteor --settings settings-development.json", 6 "start": "meteor --settings settings-development.json",
7 "chimp-watch": "chimp --ddp=http://localhost:3000 --watch --mocha --path=tests", 7 "chimp-watch": "chimp --ddp=http://localhost:3000 --watch --mocha --path=tests",
8 "chimp-test": "chimp --ddp=http://localhost:3000 --mocha --path=tests", 8 "chimp-test": "chimp --ddp=http://localhost:3000 --mocha --path=tests",
9 "staging": "meteor deploy staging.meteor.com --settings settings-development.json", 9 "staging": "meteor deploy staging.meteor.com --settings settings-development.json",
10 "production": "meteor deploy production.meteor.com --settings settings-production.json" 10 "production": "meteor deploy production.meteor.com --settings settings-production.json"
11 }, 11 },
12 "devDependencies": {}, 12 "devDependencies": {},
13 "dependencies": { 13 "dependencies": {
14 "chimp": "^0.33.0", 14 "chimp": "^0.33.0",
15 "react": "^0.14.8", 15 "react": "^0.14.8",
16 "react-addons-pure-render-mixin": "^0.14.8", 16 "react-addons-pure-render-mixin": "^0.14.8",
17 "react-bootstrap": "^0.28.4", 17 "react-bootstrap": "^0.28.4",
18 "react-dom": "^0.14.7", 18 "react-dom": "^0.14.7",
19 "react-mounter": "^1.1.0", 19 "react-komposer": "^1.7.1",
20 "react-router": "^2.0.1", 20 "react-router": "^2.0.1",
21 "react-router-bootstrap": "^0.20.1" 21 "react-router-bootstrap": "^0.20.1"
22 } 22 }
23 } 23 }
24 24