Skip to content

MangoBass Consulting

React Best Practices - Anoymous Functions

Posted tutorial, javascript, react, coding, technical


Psst, if you wanna skip ahead to the final code example, click here.

You shouldn't use anonymous functions as props in React. But why?

Anonymous functions are considered an advanced concept in React, but they shouldn't be! Understanding exactly what anonymous functions are (and why they can be harmful when mishandled in a React app) will save you a lot of time and tears when debugging any Javascript (JS) project.

This post will cover the following:

What is an Anonymous Function?

An anonymous function is a function that doesn't have a name. That's it!

It's important to understand the difference between an anonymous function and a named function. For example, take a look at this forEach method:

forEach takes a callback (function). The callback provided to forEach in this example is a legitimate function, but it does not have a name.

The code above is essentially the same as this:

While the functions in both examples are identical in the tasks performed, there is one significant difference: in the second example, the callback function has a name, logItem.

Named Functions Are Reusable

One of the benefits of the logItem function is that, as a named function, it can be called anywhere within this scope. It is impossible to reuse anonymous functions.

If I had used an anonymous function as a callback to forEach on line 3, then I wouldn't be able to call logItem on line 11!

Renting Anonymous Functions

Think of anonymous functions like renting a car instead of buying.

Imagine if you didn't own a car. Every time you needed to drive, you would have to find a ride to a car rental lot and fill out a bunch of paperwork before you could finally go about your errands. This model makes sense in some cases, like when you need a moving truck, because the vehicle you're renting doesn't fit your daily needs. But most people would find it unreasonable to have to visit a car rental lot everyday prior to driving to work. Buying makes the most sense in this case.

Similarly, there will be some cases where creating a named function is more overhead with no added benefit. Renting, or using an anonymous function, makes the most sense in these instances. But in most scenarios, you'll be surprised how reusable your functions can be.

Skip social media sharing links
Are you renting functions when you should be buying?

Object (And Function) References

Javascript treats functions for all intents and purposes as an object. According to MDN, an object is a value in memory which is possibly referenced by an identifier.

...Wait, what? Let's break this down a little bit.

Primitive Types

Before we dive into what objects are, we need to talk a little bit about what they are not. Objects are non-primitive.

According to MDN, a primitive is data that is not an object and has no methods. There are 6 primitive data types in JS:

Variables of a primitive data type are assigned a value. Each additional assignment provides a new value. The following code example demonstrates how new values are assigned:

When I called incrementNumber, a new value was created by combining the values of n (27) and 1 to make a new primitive value, 28. The original value in the number variable doesn't mutate.

Non-Primitive Types

There are 4 non-primitive data types in JS:

*Null is a unique case, because every Object is derived from null value.

Variables of a primitive data type are assigned a reference. Each additional assignment mutates the original data.

Let's look at another code example:

If you make a change to a non-primitive type, that change will be applied to every instance of that object. This is because, unlike primitive types, a new object isn't being created every time you assign a variable to the object.

With non-primitives, the variable is told where in the computer's memory that data can be found. The variable will access the data, make necessary use of it, and then put it back where it belongs.

To create a unique reference for an object, destructure its values to create a copy before assiging to a variable:

Since I destructured the original object when creating the objectForFunction variable, the new object's property values were created with the primitive values of each property in the original object. In other words, instead of creating a reference to the original object, a new object was created with the same properties.

Given that an object gets mutated when you make changes to it, it isn't even necessary for the function to return your object. In fact, I've stopped doing this in a lot of my code so that it's easier for me to remember when I'm working with a reference instead of a value:

The single instance of newObject living in memory gets mutated. No return needed.

A Closer Look At Functions

Now that we understand anonymous functions and non-pimitive types, let's take a closer look at functions.

Skip social media sharing links
Non-primitive data can be referenced using its name. Because anonymous functions don't have a name, there is no way for the computer to know if two functions are identical.

To create a reference to a function, you must assign it to a variable:

React

Having covered vanilla JS first, there isn't much to talk about specific to React.

Let's review what we've learned so far:

  • Anonymous functions are functions that do not have a name and can't be reused
  • There are two data types in JS, primitive and non-primitive
  • Primitive variables have a value, non-primitive variables have a reference
  • Mutating a non-primitive mutates it for all references
  • You cannot reference anonymous functions, because non-primitives are referenced by their name

Combining these topics, one can conclude that anonymous functions can be dangerous as React props.

Anonymous Functions as Props

Using an anonymous function as a prop looks something like this:

Without a reference to compare, MyOtherComponent has no choice but to re-render, because as far as it can tell, it just received a new prop. Depending on what's happening each time you render MyOtherComponent, this can become very expensive!

Named Functions as Props (Show Me the Code!)

There is an important detail in this code example you won't want to miss.

Not only am I supplying a named function as a prop, I am placing the callback outside of the scope of my component function.

Reference is relative to scope. In other words, if myCallback had been inside the closure of MyComponent, a new reference would be created each time MyComponent re-renders. We might as well keep an anonymous function in that case!

Conclusion

Like many concepts in React, the best way to learn is to learn more about JS itself.

This is an intermediate subject. If you are a new developer and found any of this discouraging, continue to learn. Reference (pun intended) this post periodically, and see if it becomes easier to understand over time. I doubt a question like this would come up in interviews for junior positions.

Thanks for reading!

Subscribe to be the first to get the latest from Leo!

Share This Article


About the Author: Leo Yockey

Leo Yockey (he/him/his) is the Founder of MangoBass Consulting. He is also a co-founder of Hackertunity and an advocate for underrepresented technologists. If you enjoy his writing, you can see more on his personal blog or twitter.