Reputation: 41
I'm confused about how I'm supposed to raise events from a child component using hooks (or stateless components rather). Maybe I'm thinking too much. Or not enough! I have built a simple example illustrating my confusion.
Say we have a parent component with some data
import React, { useState } from "react";
import ReactDOM from "react-dom";
const Parent = () => {
const data = [
{
thing: 1,
info: "this is thing 1"
},
{
thing: 2,
info: "this is thing 1"
},
{
thing: 3,
info: "this is thing 3"
}
];
function handleClick(item) {
console.log(item);
}
return (
<div>
<h1> This is the Parent </h1>
<Child data={data} onShowClick={handleClick} />
</div>
)
};
And child components created from mapping through the data
const Child = (data, {onShowClick}) => {
return (
<ul>
{ data.data.map(item => {return (
<li key={item.thing}>{item.info}
<button onClick={() => onShowClick}>Click</button>
</li>
)})}
</ul>
)
}
If this was all found in the same component I would do something like
onClick={() => handleClick(item)}
But you can't pass an argument with a prop.
onClick={(item) => onShowClick}
// Or
onClick={onShowClick(item)}
Maybe hooks are confusing me. Any direction would be appreciated.
Upvotes: 3
Views: 6256
Reputation: 1773
This has nothing to do with hooks
.
You should check the documentation on how to pass arguments to event handlers: https://reactjs.org/docs/handling-events.html#passing-arguments-to-event-handlers
This is the example from the documentation.
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
But since you do not need e
, you just going to pass item
{
data.data.map(item => (
<li key={item.thing}>{item.info}
<button onClick={() => onShowClick(item)}>Click</button>
</li>
))
}
Upvotes: 1
Reputation: 203
It's easy buddy. check below code. I just made some changes in you code.
const Parent = () => {
const data = [
{
thing: 1,
info: "this is thing 1"
},
{
thing: 2,
info: "this is thing 2"
},
{
thing: 3,
info: "this is thing 3"
}
];
const handleClick = (item) => {
console.log(item);
}
return (
<div>
<h1> This is the Parent </h1>
<Child data={data} onShowClick={handleClick} />
</div>
)
};
const Child = (props) => {
return (
<ul>
{props.data.map(item => {
return (
<li key={item.thing}>{item.info}
<button onClick={() => props.onShowClick(item)}>Click</button>
</li>
)
})}
</ul>
)
}
Hope this is helpful.
Upvotes: 5
Reputation: 222548
onClick={() => onShowClick}
is a mistake, onShowClick
function isn't called.
If a value from enclosing scope needs to be used, it is:
{ data.data.map(item => (
<li key={item.thing}>{item.info}
<button onClick={() => onShowClick(item)}>Click</button>
</li>
))}
Upvotes: 0
Reputation: 1337
I think you want to combine the 2.
onClick={(item) => onShowClick(item)}
You also need to add this
when you send the function to the child or make it a constant outside the Parent, onShowClick={this.handleClick}
Upvotes: 0