Adding Links in the Navbar

#1

From @jayair on Mon Apr 10 2017 01:02:41 GMT+0000 (UTC)

Link to chapter - http://serverless-stack.com/chapters/adding-links-in-the-navbar.html

Copied from original issue: https://github.com/AnomalyInnovations/serverless-stack-com/issues/35

#2

From @cgdobre on Thu Aug 31 2017 12:49:33 GMT+0000 (UTC)

I found it better to use the IndexLinkContainer component from react-router-bootstrap instead of declaring our own RouteNavItem and mixing up Routes with Links. This way the code looks like:

<Navbar.Collapse>
  <Nav pullRight>
    <IndexLinkContainer to="/signup">
      <NavItem>Signup</NavItem>
    </IndexLinkContainer>
    <IndexLinkContainer to="/login">
      <NavItem>Login</NavItem>
    </IndexLinkContainer>
  </Nav>
</Navbar.Collapse>

And I can keep my routes organized:

<Switch>
      <Route exact path='/login' component={Login} />
      <Route exact path='/signup' component={Signup} />
      <Route exact path='/' component={Home} />
</Switch>
#3

From @jayair on Thu Aug 31 2017 17:53:01 GMT+0000 (UTC)

@cgdobre Yeah initially I had written the tutorial using react-router-boostrap but it made more sense to go over how to better use the Route component instead of adding an extra dependency. This way of using the Route to conditionally render components can be very helpful in a lot of other cases.

Thanks for adding the comment. I’m sure a lot of other folks will prefer your approach.

#4

From @tommedema on Thu Oct 19 2017 05:23:13 GMT+0000 (UTC)

@jayair would it be an idea to elaborate on this more? Honestly I find it rather confusing that we are defining a Route in a place where we are actually needing a Link? The only difference with this Route and the ones in the Router are that this one has a children parameter and the others have a component parameter. But why does this make sense and why not use a Link? We’re trying to link to the login and register routes, right? And we’re not trying to define new routes.

#5

From @jayair on Thu Oct 19 2017 17:44:08 GMT+0000 (UTC)

@tommedema Yeah I can expand on this in the chapter. The issue partly is that in React Router v4, the Route component is used for conditional rendering and not just registering a route.

#6

From @x11joe on Tue Nov 07 2017 11:40:14 GMT+0000 (UTC)

This chapter was the hardest for me to understand of all the chapters. In particular I’m not sure how export default props => works? and what does {...props} mean in the code snippet below.

import React from "react";
import { Route } from "react-router-dom";
import { NavItem } from "react-bootstrap";

export default props =>
  <Route
    path={props.href}
    exact
    children={ ({ match, history }) =>
      <NavItem
        onClick={ e => history.push(e.currentTarget.getAttribute("href")) }
        {...props}
        active={match ? true : false}
      >
        {props.children}
      </NavItem>
    }
  />;

Everything else makes sense after doing some research into react router apis. I think a link to their documentation would be helpful in the article at this point.

#7

From @jayair on Tue Nov 07 2017 18:49:12 GMT+0000 (UTC)

@x11joe Yeah I can see how this can be confusing. Let me see if I can explain it a bit better.

export default props => 

can be re-written as:

export default function(props) {

And for { ...props } (or the spread operator) where let’s say props is:

props = {
  key1: 'value1',
  key2: 'value2'
};

Which means:

<NavItem
        onClick={ e => history.push(e.currentTarget.getAttribute("href")) }
        {...props}
        active={match ? true : false}
      >

Would really be:

<NavItem
        onClick={ e => history.push(e.currentTarget.getAttribute("href")) }
        key1="value1"
        key2="value2"
        active={match ? true : false}
      >

But we are applying the props dynamically.

The spread operator in JSX can be very convenient when you are composing React components the way we are doing in this chapter. It allows you to easily apply the passed the props to the component you are trying to return.

#8

From @x11joe on Tue Nov 07 2017 22:59:39 GMT+0000 (UTC)

Thanks so much for your response, I wasn’t aware you could do that with JSX. I’m still new to the features of JSX and only know the older Javascript really well at the moment. I wasn’t aware it could do shorthands for functions either. Thanks for your explanation it really makes a lot more sense now. I suppose that means ({match,history}) => is also shorthand for a function. I read up on children and its supposed to be equal to a function.

That said, if export default props => translate to this, export default function(props) {, where exactly are the props coming from. What values from props do we need for the tutorial to work for example? What are the exact values being copied into via the shorthand {…props}, I think this will help me understand it better. Thanks again for your response! (and great tutorials!)

#9

From @x11joe on Tue Nov 07 2017 23:43:04 GMT+0000 (UTC)

You know what I may have answered one of my own questions if you can confirm, the code in App.js says the following <RouteNavItem href="/signup">Signup</RouteNavItem>, is the props referring to just href here? (in this case only one property). I assume the reason you wrote the code as {…props} was in case we added more properties in the future so they automatically copy over. I was experimenting by adding properties manually and commenting out the …props and this seems to be where its coming from.

#10

From @jayair on Thu Nov 09 2017 18:21:21 GMT+0000 (UTC)

@x11joe Yeah that’s exactly it. The reason we do { ...props } is to dynamically apply all the passed in props instead of hard coding them.

#11

From @harleyguru on Wed Jan 31 2018 21:55:47 GMT+0000 (UTC)

@jayair Thanks for your amazing guide at first!

While I walk through your tutorial so far, this was the hardest chapter for me too…
I have just basic react knowledge and so this is somewhat difficult for me to understand fully.

Especially, I always have troubles with how to find all available props or methods of any react component (ex: Route component used here).
Any good and unified way to find full documentation of any React component?

I hope your quick help.
Thanks

#12

From @jayair on Wed Jan 31 2018 23:45:59 GMT+0000 (UTC)

@harleyguru I’m not sure about the unified docs but I’ve found the React Router docs to be very helpful. Here is the one to the Route component, in case you haven’t seen it before - https://reacttraining.com/react-router/web/api/Route

We also try to not use a lot of external libraries so you don’t have to refer too much too these.

#13

From @harleyguru on Thu Feb 01 2018 00:34:29 GMT+0000 (UTC)

@jayair Thanks so much for your quick and sincere help!

I got the fact there is no unified docs for React components. I’ve been working as a iOS developer and loved so much Apple’s documentation.

But while I move onto the other platforms, I have so troubles in finding good documentations for components.

My one asking is that you didn’t put so much detailed explanation regarding React basics and ES7 in React chapters, and it makes my understanding somewhat difficult.

That’s it!
Very good tutorial with details and logical explanation!

#14

From @harleyguru on Thu Feb 01 2018 00:36:13 GMT+0000 (UTC)

@jayair btw, could you also write some tutorials like this for using Firebase and Angular?

#15

From @harleyguru on Thu Feb 01 2018 06:44:03 GMT+0000 (UTC)

@jayair , btw I’ve found out some small points in your code:
<NavItem onClick={e => history.push(e.currentTarget.getAttribute("href"))} {...props} active={match ? true : false} >

here, {…props} itself will place href prop in NavItem element, so wondering why you used onClick for that purpose again.

Any specific reason why you used onClick function there?

#16

From @farrantch on Sat Feb 03 2018 22:29:12 GMT+0000 (UTC)

Hey jayair, I ran into a small issue that I thought I would share here.

I believe that the RouteNavItem object should be wrapped with LinkContainer from react-router-bootstrap. I had some dynamic content on my pages and the absent LinkContainer caused each of my pages to reload twice when navigating between them.

See here: https://stackoverflow.com/a/36933127

Code ends up looking like this:
<LinkContainer to="/somepage"><RouteNavItem>SomePage</RouteNavItem></LinkContainer>

1 Like
#17

From @jayair on Mon Feb 05 2018 18:28:39 GMT+0000 (UTC)

@harleyguru The href ensures will make the page reload and go the URL. The onClick on the other hand uses React Router to update the URL of our app and does not need a reload.

@farrantch Hmm that’s a bit strange. It shouldn’t happen but the LinkContainer is a good option here and makes sense as well.

#18

From @dwavid on Fri Feb 09 2018 21:49:35 GMT+0000 (UTC)

I’m getting the same thing where the page is refreshing twice.

#19

From @jayair on Mon Feb 12 2018 19:49:31 GMT+0000 (UTC)

@dwavid @farrantch Can you maybe share your repo so I can see what is going on? It might be an update to one of our dependencies.

#20

From @enzoferey on Tue Feb 20 2018 23:12:17 GMT+0000 (UTC)

Same here. @farrantch solution worked for me. I just did every step in the tutorial (nothing more), should be easy to reproduce :slight_smile: