Handling Local Links

In notebook:
Building Modern Web Apps
Created at:
2016-01-21
Updated:
2016-01-21
Tags:
React libraries JavaScript
Click on links without a full page refresh

First learn the problem

What we want is define a handler for clicks*. 

*like this:
  // handling event concept

React.createClass({
    onClickHandler(event){//dostuff}
    render () {
        return 
        <div onClick={this.onClick}>
        // ...
    }
})
React is handling all the DOM so the events we get are not the native JavaScript DOM events

you can still do
​event.preventDefault()​ 
it's spec compliant in IE9 (cross browser compatibility)

We want to keep normal ​<a>​ tags, etc. don't create a parallel system. Control click, etc.
Copy link address should work also
We still have to be able find out if a link is an internal or external link
​window.location​ is the obvious candidate for this, but there are oddities. some browsers add port number 80 (as a default, etc.)
What we need in summary:
  • figure out internal/external
  • target blank
  • modifier keys
  • browser consistency
  • find the real target (if there's a span inside an <a> then the event target is the span)
There's a great library for this: local-links 
So the above concept becomes:
  // **** layout.js ****
import React from 'react'

// ++++ 1. import localLinks
import localLinks from 'local-links'

export default React.createClass({
    
    // ++++ 2. handle clicks
    onClick (event) {
        const pathname = localLinks.getLocalPathname(event)
        if(pathname){
            // ++++ 4. we detected internal navigation
            event.preventDefault()
            // ++++ 5. navigate internally
            // using the "app" global for now, will change it later
            app.router.history.navigate(pathname)
        }
    }
    
    render () {
        return (
            // pase the layout html stuff here...
            // ++++ 3. add the onclick listener
            // e.g.
            <div onClick={this.onClick}>// ...
            // ++++ 5. NOTE: the above will bubble up from anywhere inside this DIV!
             {this.props.children}
            )
    }
})
The click will bubble from anywhere inside the div element where we added the listener!

Locallinks just compares if the click is for an internal link or external and all the above questions (modifier, etc. etc.)

Most frameworks do this internally, as "magic". 

It works the same with hash (#) routing