Unique HTML IDs in React - now as a module

I have now made an NPM module that solves the problem of getting unique IDs for HTML DOM elements. The module is still lacking proper server-side rendering support, but is otherwise a drop-in solution to get IDs for DOM elements.

    class MyComponent extends React.Component {
        constructor() {
            super()
            enableUniqueIds(this)
        }

        render() {
            // Get unique IDs for HTML DOM elements.
            // an entirely automatic one or via a key unique to this
            // instance of the component.
            return (
                <form>
                    <div className="form-group" key={index}>
                        <label htmlFor={this.nextUniqueId()}>
                        <input id={this.lastUniqueId()}
                            type="text"
                            className="control" />
                    </div>

                    <div className="form-group">
                        <label htmlFor={this.getUniqueId('input')}>Name</label>
                        <div className="help-block"
                            id={this.getUniqueId('help')}>
                            This should be your full name.
                        </div>
                        <input id={this.getUniqueId('input')}
                            type="text"
                            aria-describedby={this.getUniqueId('help')}
                            className="control" />
                    </div>
                </form>
            )
        }
    }

You can install the module via npm: npm install --save-dev react-html-id

What USB-C cable do I need?

Having recently acquired a new MacBook Pro, I’ve been looking for the proper cables to complement it. Mainly, I want a cable that I can charge both the Mac and other USB-C devices with, as well as use to connect USB-C devices. You would think you just get a USB-C to USB-C cable and be done with it, but it’s not so easy.

There are actually four different USB-C to USB-C cables being sold, and they all support different types of connections:

  1. USB-C Charging cable — This is the standard USB-C cable that the Mac comes with. However, what is not stated is that this is actually a USB 2.0 cable, with USB-C ports and extra pins for faster charging. This cable cannot be used to connect a USB 3.1 disk for example. A dead giveaway of USB 2.0 cables is that it is longer than 1 m (3 feet). USB 3.1 cables must be 1 m or shorter to work.
  2. Belkin USB-C 3.1 cable — This is the USB 3.1 version of the above cable, it supports USB 3.1 data connection (you can note the length is 1 m) and Power Delivery, which means it can charge the MacBook and all other accessories. You can also use this it to power USB 3.1 devices like the new LG UltraFine 4K display.
  3. Thunderbolt 3 cable with PD — Yes, there is a seperate cable for Thunderbolt 3. This is NOT the same as a USB 3.1 cable, as it has extra wires (making it thicker). This is the only cable you can use to connect the LG UltraFine 5K display. Confusigly, this cable also comes in a 2 m version. It is important to note that Thunderbolt 3 cables are not USB 3.1 cables! You can not use this cable to connect the LG 4K display for example, it will only work properly with the 5K display. There are also optical Thunderbolt 3 cables, which have longer length (up to 30 m) but cannot supply enough power for a MacBook.
  4. USB-C 3.1 cable (without USB-PD) — Thankfully Apple does not sell this cable, but there are also USB 3.1 cables that carries data. But do not support USB-PD (power delivery), these cannot be used to charge your new MacBook, but can be used to connect external hard drives as an example. If you buy a USB-C external hard drive it is likely this is the type of cable you get with it.

All in all, this is massively confusing. I would not want to be the Best Buy employee trying to explain what cable you need to buy to plug in your new device, because there is not one cable that supports all alternate modes. Your safest bet is to get the Belkin cable because it supports all regular USB 3.1 features. But it can’t be used for any of the alternate modes (Thunderbolt, DisplayPort, MHL or HDMI).

So why are there four kinds of USB-C to USB-C cables? I think the wish from the standard committee was to not sacrifice the range and slenderness of USB 2.0 cables, but still support the higher data and power rates necessary for USB 3.1. You don’t want a Thunderbolt 3 cable to charge your phone (because it is massive). So to solve this they made alternate cables for different purposes.

How to add spaces in the OSX Dock

Most common question I get after presentations, is: “How do you add those spaces in the Dock?”. So to appease the crowd, run this in your terminal:

defaults write com.apple.dock persistent-apps -array-add "{'tile-type'='spacer-tile';}" && killall Dock

This will add a spacer to the rightmost in the Dock.

Look at those delicious spacers between items.

After being added, you can move the spacers around like any other static icon to get the groups you like, and you remove them by right clicking like any other icon.

A generic handleChange function for React forms

A short trick while coding forms in react, where several variables are bound in to the state of the current component. The naive way of implementing it is having several handleNameChange, handleAgeChange, handleAddressChange etc. functions for all fields. You will end up with a lot of boilerplate code this way.

You can easily and cleanly avoid this by reusing the name attribute on input fields, and having a generic change handler that reads the name from the field, and updates state with the same.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import React from 'react';
import TranslatedComponent from '../utils/TranslatedComponent.js';

class CreditCardForm extends React.Component {
  constructor() {
    super()

    this.state = {
      name: '',
      address: '',
      ccNumber: ''
    }
  }

  handleChange(e) {
    // If you are using babel, you can use ES 6 dictionary syntax { [e.target.name] = e.target.value }
    var change = {}
    change[e.target.name] = e.target.value
    this.setState(change)
  }

  render() {
    return (
      <form>
        <h2>Enter you credit card details</h2>

        <label>
          Full Name
          <input type="name" onChange={this.handleChange.bind(this)} value={this.state.name} />
        </label>

        <label>
          Home address
          <input type="address" onChange={this.handleChange.bind(this)} value={this.state.address} />
        </label>

        <label>
          Credit card number
          <input type="ccNumber" onChange={this.handleChange.bind(this)} maxlength="16" value={this.state.ccNumber} />
        </label>

        <button type="submit">Pay now</button>
      </form>
    )
  }
}

If your form gets it’s content from Redux, you can generalize the same way, but having handleChange call this.props.onChange or similar with the change object instead.

Benedict Slaney on the new Mackbook Pros

A theory on why the new Macbook Pro is the way it is:

The Federal Aviation Administration has capped the maximum allowable size of laptop batteries on flights to 100 watt-hours. That explains why Apple’s 2015 pro model contains precisely a 99.5 watt-hour battery

The price for 32 GB RAM AND retaining 10 hour battery life would have made the Macbook heavier, and possibly brought it over the 100 Watt limit. It then makes perfect sense for Apple to skip the 32 GB, and reduce battery size as much as possible while retaining battery-life. The weight savings are the result of this choice.

In my opinion the new Macs look great and I don’t at all understand the online outrage right now. My gripe with Apple is the products they don’t update. The one’s they do update all look great!

Doing split modules in webpack

I have several directories of JavaScript code, each representing a seperate module. I would like each directory to compile to a JS bundle. While the common code between them is in a `common.js` bundle. Then the bundle for each page can be loaded separately while the common bundle is always loaded.

I’ve struggled with the answer to this question for months. While I’ve realized it is possible, the examples I’ve found are bad, or do not work. And the documentation for webpack is as always arcane on the subject, making it very difficult to do it from scratch yourself.

However, I have finally managed to get it working through the Code Splitting plugin. Below is the configuration to use for webpack:

var webpackConfig = {
  // cheap source maps (only line numbers, not column numbers)
  devtool: 'eval',

  output: {
    filename: '[name].js',
  },

  entry: {
    // Here  you list the modules you would like outputted, with the corresponding directory
    'webpack-bundles/main': src + '/modules/main',
    'webpack-bundles/intro-guide': src + '/modules/intro-guide',
    'webpack-bundles/charts': src + '/modules/charts',
  },

  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        loader: 'babel',
        exclude: ['/node_modules/', '/bower_components/'],
        query: {
          plugins: [],
          cacheDirectory: true,

          // Use stage 2 ES6
          presets: ['react', 'es2015', 'stage-2']
        }
      }
    ]
  },

  resolve: {
    extensions: ['', '.js', '.jsx'],
  },

  plugins: [
    // Split into multiple modules, required to make this example work
    new webpack.optimize.CommonsChunkPlugin("webpack-init.js")
  ],
};

Running webpack (through gulp in my case) after this should result in the following:

Terminal showing webpack code splitting outputting four files, screenshot.
Great success!

This results in webpack creating four different modules. The webpack-init.js must be included on every page, and includes the common code for the modules (libraries etc.) and also the webpack bootstrap code. The other modules contains the compiled code from that folder.

Then the question is; how to load the modules dynamically on demand? In my case the entire page is NOT a React component, only parts of the page are. And I mount separate React components in different places in the DOM.

To solve this, I have a function that wraps ReactDOM.render with a check if the module is loaded, in that case it just forwards the call, otherwise it injects the script tag for that module.

var loadedModules = {}

function mountComponent(module, component, props, domNode) {
    function mountIt() {
        ReactDOM.render(React.createElement(component, props), domNode)
    }

    if (!loadedModules.hasOwnProperty(module)) {
      // Not mounted already, add the script tag on document.ready
      document.addEventListener('DOMContentLoaded', function() {
        var s = document.createElement('script')
        s.type = 'text/javascript'
        s.src = document.location.origin + '/dist/webpack-bundles/' + module + '.js'
        document.body.appendChild(s)

        loadedModules[module] = true

        mountIt()
      }, false)
    }
    else {
        mountIt()
    }
}

// Use it
mountComponent('intro-page', 'IntroPageApp', {}, document.getElementById('intro-container'))

This solution works great for intermingling React and native HTML for a page. If your situation is different, and your entire page is a React app you will need to modify this approach, by using require.ensure([dependencies], callback) instead. I have not tried this yet, but it should not require any changes to the webpack configuration above to implement.

Taking PHP seriously

I agree with almost everything in this post. While PHP has it’s warts, it’s a highly productive language thanks to it’s short development cycle (no need to restart the server, zero boilerplate) and simple semantics (no server-global state, only request-global).

Several of the sites I run are coded in PHP, and while it could be prettier, it works just fine. My main gripe with PHP is the naming inconsistencies, but the amazing documentaion makes up for it.

The Hacker News comment thread is filled with insight on the subject as well.

In the future, Chrome will flag HTTP sites as insecure

There has been a proposal for a long time in Chrome to flag HTTP as insecure. The motivation for this is: all sites over HTTP are entirely lacking encryption, so why should they appear “safe” while sites with weak encryption trigger warnings? The sensible thing to do is to have an even stronger warning for these sites.

Chrome has for a long time supported the option mark-non-secure-as — which can be accessed by going to chrome://flags/#mark-non-secure-as and selecting “Mark non-secure origins as non-secure” (fitting name for an option) in the dropdown. After enabled, this is what you’ll see in the address bar upon visiting an HTTP site:

Shows the Chrome Canary address bar, visiting an HTTP site. The bar shows an insecure message, screenshot.
How visiting an HTTP site appears in Chrome 55 (scheduled to be released in December). This will certainly scare users away from your site.

There is no decision on when this change will become the default and the web is not ready for this just yet. An interesting way to go would be to incrementally make the icon color more red over a period of years. This would slowly motivate people to switch to HTTPS.

To get with the times, it might be a good idea to set up Let’s Encrypt. You certainly don’t want to trigger the warning above, once the time for it comes.

subscribe via RSS