Understanding Function References and Lazy Evaluation in React

Let’s break down the following code in detail for a beginner to React:

 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
export default function App() {
  return (
    <Toolbar
      onPlayMovie={() => alert('Playing!')}
      onUploadImage={() => alert('Uploading!')}
    />
  );
}

function Toolbar({ onPlayMovie, onUploadImage }) {
  return (
    <div>
      <Button onClick={onPlayMovie}>
        Play Movie
      </Button>
      <Button onClick={onUploadImage}>
        Upload Image
      </Button>
    </div>
  );
}

function Button({ onClick, children }) {
  return (
    <button onClick={onClick}>
      {children}
    </button>
  );
}
  1. export default function App() {...}: Here, we’re defining a function called App. This is the main component of our application. It’s the highest level component, the parent of all other components. The export default part means that we are making this function the default export of this module, so it can be imported into another module using an import statement.

  2. return (...);: This is what the App function (and thus our component) returns when it is rendered. The stuff inside the parentheses is JSX, a syntax extension for JavaScript that allows us to write HTML-like code inside our JavaScript. In this case, it’s returning a Toolbar component with certain props.

  3. <Toolbar onPlayMovie={() => alert('Playing!')} onUploadImage={() => alert('Uploading!')} />: Here we’re rendering a Toolbar component. We are also passing two props to the Toolbar component: onPlayMovie and onUploadImage. Each of these props is a function that displays an alert when called.

  4. function Toolbar({ onPlayMovie, onUploadImage }) {...}: This defines a new component called Toolbar. The curly braces {} in the parameter of the function are used for destructuring, which allows us to extract multiple properties from an object in a single statement. This Toolbar component takes two props, onPlayMovie and onUploadImage, which were passed to it by the App component.

  5. <Button onClick={onPlayMovie}>...<Button onClick={onUploadImage}>...: Here we’re rendering two Button components and passing them each an onClick prop. The value of the onClick prop is a function that we received from the parent App component. When the button is clicked, it will execute the corresponding function, showing an alert.

  6. function Button({ onClick, children }) {...}: This is the Button component definition. It takes two props, onClick and children. The onClick is a function that will be executed when the button is clicked. The children prop is a special prop in React, which is used to display whatever you include between the opening and closing tags when invoking a component.

  7. <button onClick={onClick}>: Here we have a standard HTML button element. We’re assigning the onClick prop that we received from the parent Toolbar component to the onClick attribute of the button element. When this button is clicked, it will execute the function that was passed to it from the Toolbar component.

  8. {children}: This is where we render the children prop. Whatever is passed as children to the Button component when it’s used will appear here.

To summarise, this is a simple React application with three components (App, Toolbar, Button) where clicking on buttons in the Toolbar triggers alerts as defined in the parent App component.

Lazy Evaluation

The function onClick is a reference to a event handler. The value of the onClick argument could be either onPlayMovie or onUploadImage. These methods: onPlayMovie and onUploadImage when they are passed in to the Button component using { onPlayMove } is basically a reference to the function. So it does not get executed immediately. It is delayed execution based on the onClick event on the Button component. Because of functional nature of JavaScript we are able to pass functions as arguments to methods.

In JavaScript, functions are first-class citizens, which means you can do with them what you would do with other types such as strings or numbers. You can store them in variables, pass them around as arguments, return them from other functions, and so on.

In the case of the onClick prop in your React component, you’re passing a reference to a function (either onPlayMovie or onUploadImage) to be executed when a click event occurs on that component. These functions are not invoked immediately when the component is rendered; instead, they are only invoked in response to a click event. This pattern is called “higher-order functions” and it’s a cornerstone of functional programming, a paradigm which JavaScript supports.

This kind of delayed execution is sometimes referred to as “lazy evaluation”, as the evaluation of the function is delayed until it’s actually needed. It’s a powerful technique that can help you write more efficient and flexible code.

React makes heavy use of this functional nature of JavaScript. It allows you to create components (which are essentially functions) and use them to build complex user interfaces with interactivity built in, like responding to user events with functions passed as props.