Why don't we set the event listener attribute value to a function call?

Question

Why don’t we set the event listener attribute value to a function call?

Answer

If we set the event listener attribute value to a function call, the function will get called automatically on the page load (when our JSX element renders to the browser) instead of listening for the event and then calling the function.

For example:

import React from 'react';
import ReactDOM from 'react-dom';

function switchHeading() {
  console.log('switchHeading was called!'); 
}

const heading = (
  <h1 onClick={switchHeading}>Click Me!</h1> // onClick will listen for the click event, then will call switchHeading. When that occurrs we will see 'switchHeading was called!' logged to the console
  // if <h1 onClick={switchHeading()}>Click Me!</h1> is used instead, and we set onClick to a function call, we will see 'switchHeading was called!' logged to the console immediately when our JSX renders and not on the click event
)

ReactDOM.render(heading, document.getElementById('app'));
9 Likes

I do not understand how the {switchHeading} and {switchHeading()} translate to an HTML code when the browser loads the page. Can you clarify further?

2 Likes

If I’m not mistaken, the JSX elements shown by the OP are not translated into HTML, but are introduced in the document through the DOM. We could, however, say that the HTML equivalent of the JSX element

<h1 onClick={switchHeading}>Click Me!</h1>

would be

<h1 onclick="switchHeading()">Click Me!</h1>

Take note of the parentheses in the onclick attribute, which have to be there according to the documentation (see, e.g., https://www.w3schools.com/jsref/event_onclick.asp).

Assuming that we have an HTML element <h1 id="header">Click Me!</h1>, we also have (at least) two equivalent ways of implementing the equivalent of the OP’s JSX element in JavaScript, namely, by defining the interactive behavior through

document.getElementById('header').onclick = switchHeading;

or through

document.getElementById('header').addEventListener('click', switchHeading);

Note that switchHeading is not accompanied by parentheses, here! We are just providing a reference to the function that should be executed once our h1 element is clicked. If we wrote switchHeading(), something different would happen. As explained by the OP, the function switchHeading() would then directly be called upon loading of the page and will not wait for the element to be clicked.

For more information, please refer to the course at https://www.codecademy.com/learn/build-interactive-websites.

5 Likes

But afaik, there is a difference between document.getElementById('header').addEventListener('click', switchHeading); on the one hand side and document.getElementById('header').onclick = switchHeading; or <h1 onclick="switchHeading()">Click Me!</h1>.
The first solution allows more click eventlisteners to be added, while multiple calls of the second solution would override the existing eventlistener for that element.
Because of that, it would be very useful, to know how React adds the Eventlistener internally. On my opinion the proper solution is always the first. Can I use it to add different click events to a corresponding (real) DOM object, if it exists, without generating a conflict? Also does React remove the once added onClick eventlistener, when it is dynamically changed in another line via React?

2 Likes

I have a silly question but it’s just out of curiosity.

In this lesson, after I make a “Click” on the Kitty’s Image it turns into a Dog because of the function “makedoggy”, I totally get that part, but what could I add if I wanted to turn that Dog picture into the Kitty image again? like, being able to switch back and forth between both images.

Thanks in advance :slight_smile:

1 Like

What if I want to call a function with arguments? The same syntax will not work.

This is not stupid question at all!
This should be a next practice exercice from codeacademy.
In this way will helpful to play with some conditional logic together with events.

That’s a great idea to do.

To be able to turn the images back and forth, I did:

  • assign the alt text of the image to a variable (‘pet’) when the image is clicked. (this is done by using .getAttribute())
  • if the variable ‘pet’ is ‘kitty’, then the image and alt text are changed to that of the ‘doggy’
  • else, the image and the alt text are changed to that of the ‘kitty’.
  • I used the alt tag because it gives an info about the current image being displayed. So, using this information, I could then use if-else to determine its outcome.
1 Like

const changeName = (params) => console.log(params)

// call a function with arguments
const button = <button onClick={ () => changeName(‘your name’) }>changeName

I notice that that the function onClick that is references takes parameter (e). However, when we add the function to onClick, we are not passing it any parameters. What is happening? Why does this work?

import React from 'react'; import ReactDOM from 'react-dom'; function makeDoggy(e) { // Call this extremely useful function on an <img>. // The <img> will become a picture of a doggy. console.log(e); e.target.setAttribute('src', 'https://content.codecademy.com/courses/React/react_photo-puppy.jpeg'); e.target.setAttribute('alt', 'doggy'); } const kitty = ( <img src="https://content.codecademy.com/courses/React/react_photo-kitty.jpg" alt="kitty" onClick={makeDoggy}/> ); ReactDOM.render(kitty, document.getElementById('app'));
1 Like

Here’s an example to change the image between dog and kitty.

I extract the src link and alt text of dog and kitty to an object call data. Besides, I add a boolean variable called isKitty. This isKitty variable will design which animal information would be displayed.

e.target.setAttribute('src', isKitty ? data.dog.src : data.kitty.src) is to assign the value of src based on a condition.
When kitty photo is displayed, isKitty is true. Behind the scene, it executes e.target.setAttribute('src', data.dog.src). Same logic could be found it the next line to swap the alt text.

Last line in changeAnimal(e) is to toggle the value of isKitty from true to false. We should not assign isKitty by hardcoding true or false, instead not operator ! should be used. It turns to dog after clicking the kitty image, hence isKitty should be false.

When dog photo is displayed, isKitty is false. If we click the photo, behind the scene, it executes e.target.setAttribute('src', data.kitty.src). Same logic could be found it the next line to swap the alt text. isKitty will be true again.

import React from 'react';
import { createRoot } from 'react-dom/client';

const container = document.getElementById('app');
const root = createRoot(container);

let isKitty = true;

const data = {
  dog: {
    src: 'https://content.codecademy.com/courses/React/react_photo-puppy.jpeg',
    alt: 'doggy',
  },
  kitty: {
    src: 'https://content.codecademy.com/courses/React/react_photo-kitty.jpg',
    alt: 'kitty',
  }
};

function changeAnimal(e) {
  e.target.setAttribute('src', isKitty ? data.dog.src : data.kitty.src);
  e.target.setAttribute('alt', isKitty ? data.dog.alt : data.kitty.alt);
  isKitty = !isKitty;
}

const kitty = (
	<img 
    onClick={changeAnimal}
		src={data.kitty.src} 
		alt={data.kitty.alt}  />
);

root.render(kitty);
1 Like

This is probably a dumb question, why doesn’t the dog image appear when I hit the run button even though I got the check that the code was added correctly. Is there something that I missed?

Oh my gosh, I did miss something. I just had to click on the image :sweat:

I had the same question as well. It should have been added to Codecademy’s explanation.

• "e" parameter in the makeDoggy function 
	○ Represents the event object triggered by the onClick event handler. 
	○ When the <img> tag is clicked, it invokes the makeDoggy function, passing in the event object associated with the click event.
	
• Inside makeDoggy, e.target 
	○ Refers to the element that triggered the event, which, in this case, is the <img> tag. 
	○ Is used to modify attributes of this element, setting its src attribute to an image of a dog and its alt attribute to 'doggy'.
1 Like