DEV Community

loading...
Cover image for Typescript and React: Lambdas are forbidden?

Typescript and React: Lambdas are forbidden?

jonhilt profile image Jon Hilton Originally published at jonhilton.net ・3 min read

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

I'm generally a fan of Typescript 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.

Until now creating a React Typescript project has typically involved using this Typescript Create React App template.

If you spin up an app with this template and then try to follow along with the official React javascript tutorials, chances are you'll run into Typescript errors which leave you scratching your head.

One in particular comes early and is a bit confusing if you're just starting out.

STOP PRESS! Read this first...

The rest of this article refers to an issue you may encounter if you spin up a new React Typescript project using the template found here.

But, as of "Create React App" 2.1, Typescript is "baked in"; So you can create a new Typescript React application with this command instead...

npx create-react-app app-name -typescript

This approach avoids the issues mentioned in the rest of this article!

You can check out this brief video I made showing the new CRA template in action here...

But if you're interested in TSLint and how it works (or you're still using the wmonk template) read on...

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.

You can think of "linters" as tools which check your code for potential problems before you compile and run it.

They enforce any number of rules which are considered "good practice" for specific programming languages.

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!

That said, it seems there is a general concensus that 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!

Remember you can check out this brief video I made showing the new CRA template in action here...

Discussion (1)

pic
Editor guide
Collapse
michaeljota profile image
Michael De Abreu

This a good warning and you should not disabled it. Handling good events its not simple in React. This have nothing to do with Typescript, but how React binds the event to the handler. You always should create a method to handle the event and bind your own this to that method.