I am creating a modal. This modal will be opened when any of 6 div
elements are clicked. Each of the components are created using the .map()
function to an array. The popup
parameter is supposed to be the function that runs when clicked:
items.map(item => (
<StoreItem popup={() => popup} item={item} />
))
For each item
from items
, there is a StoreItem
created. Here is the code for the StoreItem
component:
const StoreItem = ({popup, item}) => {
return (
<div onClick={popup(item)} className="...">
...
</div>
);
};
As seen above, each StoreItem
is a div
with an onClick
property that runs the popup()
function. Here’s the popup()
function:
function popup(item) {
console.log(item);
}
For some reason, when I console.log(item)
, the item
that is supposed to be passed in from the onClick
is not being logged. Rather, I’m getting a SyntheticBaseEvent
with random stuff that I don’t want.
How is this fixed so that the contents of item
are properly displayed, not some SyntheticBaseEvent
?
Thanks, any help is appreciated.
2
Answers
To make it work, you should shake parentheses a little:
This is not a react-specific question, this is how functions work in JavaScript. Let me explain some details
How to call a function
So, you created a function
To make it log something, we should call the function and pass something as a parameter, like that:
The code above logs
"hello"
, because we called the function (write parentheses after the function name) and passed the"hello"
string as a parameter to it.But when you do not write the parentheses after its name, you can treat the function as a variable. For example, you may assign a function to a new variable:
Let’s see how your code works
Take a look at the code where you render items
Here you create a new arrow function
() => popup
. The function does not take any parameters (its’ parentheses are empty), and returns thepopup
function. But again, it does not call thepopup
function, right? Because we don’t see any parentheses after the wordpopup
.Then, when rendering a single item, you do not create a new function, but call what you get as the popup property:
So, in the
popup
property you get the function you created in the parent component, right:And now, when passing to the
onClick
property, you finally call it:Right? So you call the
() => popup
withitem
as a parameter. But the() => popup
function does not take any parameter. But it returns your originalfunction popup
. So, the code is equivalent to the following:As you may see, the function takes one parameter and has no idea about your "item" variable. I intentionally named it "x" to show that the name of the variable does not matter. The function just logs what its parameter is, not some outer-scope variable.
So, when you click on the element, react captures the event and passes the event to your function.
If you’d like to understand this topic more deeply, you may read something on "higher-order functions" topic.
React is passing the event object to your function, you can’t control that by naming the parameter something else.
What you want to do is pass an anonymous function to
onClick
, in which you callpopup(item)
.What’s happening is that React will still pass the event object to the function, but you ignore that by not including it in your function definition. then in the body of the function, execute your on logic, namely, calling the
popup
function with theitem
.This is what is happening, notice that you do nothing with the event, but it is going to be the first parameter of that function, regardless.