Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comments: Adding Links in the Navbar #35

Closed
jayair opened this issue Apr 10, 2017 · 20 comments

Comments

Projects
None yet
8 participants
@jayair
Copy link
Member

commented Apr 10, 2017

@jayair jayair added the Discussion label Apr 10, 2017

@cgdobre

This comment has been minimized.

Copy link

commented Aug 31, 2017

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>
@jayair

This comment has been minimized.

Copy link
Member Author

commented Aug 31, 2017

@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.

@tommedema

This comment has been minimized.

Copy link

commented Oct 19, 2017

@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.

@jayair

This comment has been minimized.

Copy link
Member Author

commented Oct 19, 2017

@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.

@x11joe

This comment has been minimized.

Copy link

commented Nov 7, 2017

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.

@jayair

This comment has been minimized.

Copy link
Member Author

commented Nov 7, 2017

@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.

@x11joe

This comment has been minimized.

Copy link

commented Nov 7, 2017

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!)

@x11joe

This comment has been minimized.

Copy link

commented Nov 7, 2017

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.

@jayair

This comment has been minimized.

Copy link
Member Author

commented Nov 9, 2017

@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.

@harleyguru

This comment has been minimized.

Copy link

commented Jan 31, 2018

@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

@jayair

This comment has been minimized.

Copy link
Member Author

commented Jan 31, 2018

@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.

@harleyguru

This comment has been minimized.

Copy link

commented Feb 1, 2018

@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!

@harleyguru

This comment has been minimized.

Copy link

commented Feb 1, 2018

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

@harleyguru

This comment has been minimized.

Copy link

commented Feb 1, 2018

@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?

@farrantch

This comment has been minimized.

Copy link

commented Feb 3, 2018

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>

@jayair

This comment has been minimized.

Copy link
Member Author

commented Feb 5, 2018

@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.

@dwavid

This comment has been minimized.

Copy link

commented Feb 9, 2018

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

@jayair

This comment has been minimized.

Copy link
Member Author

commented Feb 12, 2018

@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.

@enzoferey

This comment has been minimized.

Copy link

commented Feb 20, 2018

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

@jayair

This comment has been minimized.

Copy link
Member Author

commented May 9, 2018

@jayair jayair closed this May 9, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.