Typescript and React: Lambdas are forbidden?

November 11, 2018 · 3 minute read

In learning React (as a .net developer) I suggested using React and Typescript together.

I’m generally a fan of Typescript (I think, for now at least) and appreciate how it catches typos/errors which might otherwise slip through the net (and into production).

But it’s important to realise that learning React using Typescript is potentially harder than learning React using Javascript.

Not least because most of the React docs, tutorials, blog posts are written using Javascript.

This means you have to figure out how the Typescript parts works, and adjust the examples you see accordingly.

Chances are high you’ll run into Typescript errors which leave you scratching your head, and one in particular comes early and is a bit confusing if you’re just starting out.

JSX No Lambda

When you start following the Tutorials, on reactjs.org for example, you’ll invariably see things like this…

<button className="square" onClick={() => alert('click')}>
    {this.props.value}
</button>

Note the onClick event handler uses the ES2015 arrow syntax (if you’re a C# developer you’re used to this being referred to as a lambda).

Now, if you try to declare an inline function like this with your React Typescript project (created with the wmonk template) you’ll run into an error.

Lambdas are forbidden in JSX attributes due to their rendering performance impact

So what’s going on?

The wmonk React Typescript template employs TSLint to enforce certain rules.

One of those rules is called jsx-no-lambda. Here’s the explanation (taken from the GitHub Repo).

Creating new anonymous functions (with either the function syntax or ES2015 arrow syntax) inside the render call stack works against pure component rendering. When doing an equality check between two lambdas, React will always consider them unequal values and force the component to re-render more often than necessary.

Now there are a number of workarounds for this. You can create a named function and reference it instead…

public render() {
    return (
    <button className="square" onClick={buttonClicked}>
        {this.props.value}
    </button>)
}

private buttonClicked = () => {
    alert('click');
}

But if you just want to follow along with the tutorials, and would like TSLint to keep out of your way while you do so, you can always disable rules in the tslint.json config file.

{
  "extends": [
    "tslint:recommended",
    "tslint-react",
    "tslint-config-prettier"
  ],
  "rules": {
    "jsx-no-lambda": false
  }
}

Here you can turn rules off as you wish.

Naturally, this demands a word of caution!

If you turn all the rules off there would be no point having TSLint in the first place! So it pays to think twice before just switching them off willy-nilly!

But (as Mark Erikson helpfully noted in the comments) the jsx-no-lambda rule is generally unnecessary and if you’re just starting, it pays to remove any friction which might get in the way.

So turn the rule off (or use the official Create React Typescript template), go forth and follow the tutorials!