What does ES6’s spread operator (…) do and what can you use it for?

Some language features are easy to guess what they do even if you’re unfamiliar with them, but it’s not immediately obvious what the ES6 spread operator ‘…’ does.

Here’s a great article that gives some practical examples of how you can use the spread operator, for example, to:

  • insert one array into another
  • copy the contents of an array
  • convert a String into an array of chars

React Flux Store: addChangeListener is not a function

Using React with Flux, you need to register a callback from your Component so that it can be called when the Store emits an event. For an ExampleComponent and ExampleStore, this might look like:

class ExampleComponent extends Component {

    constructor(props) {
        super(props);
    }

    componentWillMount(){
        ChatStore.on('change', this.handleUserNameChange);
    }
...
}

I’ve seen some examples where a helper function is declared in the Store that registers your Component as a listener, so the call from the Component to register with the Store might look like:

    componentWillMount(){
        ChatStore.registerChangeListener(this.handleUserNameChange);
    }

and in your ExampleStore you’ll declare registerChangeListener() (and similar to remove) like this:

addChangeListener(callback) {
    this.on('change', callback);
}

removeChangeListener(callback) {
    this.removeListener('change', callback);
}

All good so far, but here’s the issue I just ran into:

Uncaught TypeError: _ExampleStore2.default.addChangeListener is not a 
function
 at ExampleComponent.componentWillMount (ExampleComponent.jsx:19)
 at ReactCompositeComponent.js:348

Initially this is confusing, since it’s clear we did already declare addChangeListener, so why is this error saying it’s not a function?

The catch is in how we export the Store. The cause of my issue above was that I had exported it like this:

class ExampleStore extends EventEmitter {
..
}
export default ExampleStore;

This is how you would typically export a module but what we’re trying to do is treat the Store as a singleton instance. To do this the export should be:

export default new ExampleStore();

This approach is described in many Flux related articles (here’s an example), but it’s an easy mistake to miss.

JavaScript ES6 default imports vs named imports

I’d been wondering this for a while. What’s the difference between this style of ES6 import:

import A from './A';

vs

import { A } from './A';

I’ve seen and used both, and had guessed that the { A } syntax is when you’re importing a specific named function from a module? I wasn’t convinced this was correct. It turns out the difference is importing a default export, versus importing using a named import.

This is explained here this SO post here:

http://stackoverflow.com/questions/36795819/when-should-i-use-curly-braces-for-es6-import

React: ‘Element type is invalid … check your render method’

Once you’ve seen this error once in your React app you’ll probably instantly recognize it and know exactly what this means:

Uncaught Error: Element type is invalid: expected a string 
(for built-in components) or a class/function (for composite 
components) but got: object. You likely forgot to export your 
component from the file it's defined in. Check the render 
method of `App`.

The key is “You likely forgot to export your component…” which was exactly the issue in my case.

If you have an ES6 style component this:

class App extends Component {
...
}

… check that you’ve exported it at the end of the source file with:

export default App;