Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use Link component in React-Router instead of just anchor tag? [duplicate]

I just started on react router.

I have two questions. What is the difference between using <Link to="/page"> and <a href="page">? Both make the exact same get request to /page but I get an error when I use <a href="page"> but it works when I use <Link to="/page"> when I am nesting routes. I don't understand, how there could be any difference, when I know for fact that both render to exact same url?

Second is the weird arrow function in react router v4 documentation

const About = () => (
  <div>
    <h2>About</h2>
  </div>
)

I know () => {} these are new in ES6 but I cannot find anything on normal brackets instead of parentheses. What are they?

Edit

My index.js class (I have all the imports)

render((
    <Router>
        <div>
            <Route component={App}/>
        </div>
    </Router>
), document.getElementById('root')
);

My App.js class

class App extends Component {
render() {
    return (
        <div className="container">
            <header>
                <span className="icn-logo"><i className="material-icons">code</i></span>
                <ul className="main-nav">
                    <li><Link to="/">Home</Link></li>
                    <li><Link to="/about">About</Link></li>
                    <li><Link to="/teachers">Teachers</Link></li>
                    <li><Link to="/courses">Courses</Link></li>
                </ul>
            </header>
            <Route exact path="/" component={Home}/>
            <Route path="/about" component={About}/>
            <Route path="/teachers" component={Teachers}/>
            <Route path="/courses" component={Course}/>
        </div>
    );
}
}

export default App;

The error I'm getting. Cannot GET /about on the browser when I try to move to localhost:8080/about. However, when I click the about button, it goes to exactly the same url /about and renders perfectly

like image 775
forJ Avatar asked Mar 29 '17 07:03

forJ


4 Answers

This may be a bit late to address your issue and you may well have figured it out. But here's my take:

First:

What is the difference between using <Link to="/page"> and <a href="page">

  • On the surface, you seem to be comparing apples and oranges here. The path in your anchor tag is a relative path while that one in the Link is absolute (rightly so, I don't think react-router supports relative paths yet). The problem this creates is say you are on /blah, while clicking on your Link will go to /page, clicking on the <a href='page' /> will take you to /blah/page. This may not be an issue though since you confirmed the correctness of the url, but thought to note.
  • A bit deeper difference, which is just an addon to @Dennis answer (and the docs he pointed to), is when you are already in a route that matches what the Link points to. Say we are currently on /page and the Link points to /page or even /page/:id, this won't trigger a full page refresh while an <a /> tag naturally will. See issue on Github.

A fix I used to solve my little need around this was to pass in a state property into link like so <Link to={{pathname: "/page", state: "desiredState"}}>Page</Link>. Then I can check for this in the target component's (say <Page />) componentWillReceiveProps like so:

componentWillReceiveProps(nextProps){
  if (nextProps.location.state === 'desiredState') {
    // do stuffs
  }
}

Second question:

the weird arrow function in react router v4 documentation... I cannot find anything on normal brackets instead of parentheses. What are they?

Arrow functions; again @Dennis and @Jaromanda X have kind of addressed it. However, I've got three bits to add:

  • When you have () => blah without the curly braces {}, you are implicitly returning whatever follows the => in this case blah. But when you have curly braces immediately after the arrow, then it's now your responsibility to return something if you so desire. So () => blah (which by the way is synonymous to () => (blah)) will be more similar to () => { return blah } and not () => { blah }.
  • So what happens if you want to return an object: { blah: blah }; this is what @Jaromanda X was pointing at. You will then need to do () => ({ blah: blah }) or simply () => ({ blah }) for implicit return or you could return explicitly like so () => { return { blah: blah } }.
  • My third bit is to point you to MDN

Hope it helps.

like image 173
flash Avatar answered Oct 21 '22 06:10

flash


The href attribute would trigger a page refresh which would reset the application states. However the link and navlink of react-router doesn't trigger a page refresh. Since React is used to create single page applications most of the time make sure you choose Link or Navlink when working with routing

like image 41
mohamed amine salah Avatar answered Oct 21 '22 07:10

mohamed amine salah


The component allows you to do more than the normal link element. For instance, because it's a React component you have the benefits of having a state and what not (if you want that). You can see more documentation on here. Without the error I'm not sure what happens, but I suspect the routing library wants you to use the component, over a normal html element.

With regards to () => {} this is a construct which is called an anonymous function, or a lambda expression. It's basically the same as saving a function in a variable: var x = function(){ return (<div>...) }; if you have anything in the first parenthesis, it's a parameter which you have access to: const x = (y) => return y*2; The reason it's done in React is to expose the function scope to the component it lies in.

like image 34
Dennis Avatar answered Oct 21 '22 06:10

Dennis


There is no better then looking at the code source.

https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/Link.js

You can see that Link is a component, that internally use history. Which is the module||library behind the history and navigation for react-router. And come with different modes (in memory history, browserHistory, hashHistory. And even custom).

Yea as a similarity it render an anchor tag but the default behavior is overridden (preventDefault()). They could have used just a div. But not completely right. As for the reason bellow.

So basically it work like that:

Observe the condition bellow

  if (
          !event.defaultPrevented && // onClick prevented default
          event.button === 0 && // ignore everything but left clicks
          (!this.props.target || this.props.target === "_self") && // let browser handle "target=_blank" etc.
          !isModifiedEvent(event) // ignore clicks with modifier keys
    ) {

}

if the condition above is met. It will use history (push or replace). Otherwise it will leave the browser normal behavior. And so in that case it will be just a normal anchor tag <a />. Example letting the browser handle target='blank'. The condition are well explained. Then depending on the type of history object. The behavior change. Not the behavior of ` itself. But just the result of the history object type.

In resume:

<Link /> is a component, that render a <a /> anchor tag. However in the main conditions the default behavior is prevented (preventDefault()). That allow it to apply the change to the history object (onClick event). Which react-router navigation is based on. And on the some conditions as mentioned above. It just fall back to the browser behavior. And just be exactly a <a /> anchor tag (no preventDefault()).

For the use. If you are using React-router. Then you just need to use Link.

like image 40
Mohamed Allal Avatar answered Oct 21 '22 08:10

Mohamed Allal