0

I am currently learning React with Typescript and have come across an issue with handling event with the onClick property. I have a react component of a list of stuff from an array and I want to log into the console the item I clicked. It worked when I was referencing the item inline. I was trying to test how it would work if I moved the logic outside to a function and then having onClick reference the function. This is what I have:

enter image description here

When i do console.log("Clicked, event.currentTarget); it just shows that I clicked the list object, but say for example if I clicked New York I want the console to say "Clicked New York" and not an object with its list of properties. Before I would just have

"<li className="list-group-item" key={item} onClick={() => console.log("Clicked", item)}>;"

and it worked. I tried inspecting the object to see what properties it would have to maybe use the . operator to reference one of them to get the actual item in the array, but I couldn't find anything in the console. Is there a way to actually get the item in the array while using a function to handle the event like I have and if so what would have to be passed as the argument? I was just thinking that this may be necessary for complicated logic while also needing the name of the item in the array that is clicked. I have looked through posts on this topic and can't seem to find one.

SK99
  • 51
  • 5
  • 1
    Please can you share the code as text instead of image – Ossama Ismaili Apr 03 '23 at 23:23
  • 1
    I think you need to prevent event bubbling with ```stopPropagation```, look at this answer: https://stackoverflow.com/questions/5963669/whats-the-difference-between-event-stoppropagation-and-event-preventdefault – Chris B. Apr 04 '23 at 00:13

1 Answers1

0

I created a Code Sandbox for you here, but here's just one of many possible ways around this:

const cities = ["London", "New York", "Paris"];

export default function App() {
  const handleCityClick = (city: string) => console.log(`Clicked ${city}`);

  return (
    <div className="App">
      <ul>
        {cities.map((city) => (
          <li key={city} onClick={() => handleCityClick(city)}>
            {city}
          </li>
        ))}
      </ul>
    </div>
  );
}

https://codesandbox.io/s/modest-waterfall-1stglb

You'll note that we have to lose the elegance of onClick={handleClick} because we actually don't really want to use a mouse event handler any more, we just care about cities. So we have to use a mixture of inline and separately-defined handlers to get this; inline so that we get the closed-over value of city for this li, and a separate function to avoid putting too much complexity in among all the HTML/JSX.

As you mentioned you might need both the city AND the mouse event, you could of course supply both; e.g.:

  const handleCityClick = (city: string, mouseEvent: MouseEvent) => ...

  ...

  <li key={city} onClick={(ev) => handleCityClick(city, ev)}>
millhouse
  • 9,817
  • 4
  • 32
  • 40