Reputation: 315
My question is regarding the flow of an onClick
event in React
when clicking a div
.
My application has a ParentComponent
which calls in to a ChildComponent
and subsequently creates a div
for each member of the props.options
array in the ParentComponent
.
I have two questions which are as follows:
div
, how can I pass the onClick
event to this component? div
know which option
created it? I mean to ask, some iteration of the this.props.options
array, say, optionA
created, say, divA
, how does divA
know that it was created by optionA
and not optionB
? Is this done by React internally?This is my Parent component
interface ParentComponentState {
..
..
}
export interface ParentComponentProps {
...
...
}
export class ParentComponent extends React.Component<ParentComponentProps, ParentComponentState> {
public state: ParentComponentState = {
...
};
constructor(props) {
super(props);
}
private handleClick = (item) => {
console.log(item);
}
public render(): JSX.Element {
return (
<>
<SomeButtonComponent>
{ this.props.options.map((item: any, index: any) => (
<ChildComponent
onClick={ () => this.handleClick(item) }
/>
)) }
</SomeButtonComponent>
</>
);
}
}
This is my Child component
export function ChildComponent(props: IChildComponent): JSX.Element {
return
(
<div
ref={ ... }
className={ someClassName }
dangerouslySetInnerHTML={ { __html: someHTML } }
onClick={ props.onClick }
/>
)
}
Upvotes: 1
Views: 1869
Reputation: 6582
I would try to answer your questions to the best of my ability, so here it is:
Who controls the order of arguments in the invocation of this call?
You Do, React Only Says give me function which takes an argument and When an event
for example click event
happened I will call your function with and will send the event
object as the parameter of it.
so it's on you, if you want to have more arguments you need to some how get around this by currying arguments or binding them like below:
handleClick = (item) => (event) => {
console.log(item);
console.log(event);
}
when you doing something like this and then in the onClick
props you're calling the handle click like below:
<ChildComponent onClick={ this.handleClick(item) } />
you're actually sending
(event) => {
console.log(item);
console.log(event);
}
to your props and this is what React wants(A function which takes an argument and will call it when event happpens)
See Event Handling in React Docs
How does the browser know to pass in only the second argument as the actual event? As I said above, React has its own Event System on top of browser Event System (Read about it here),
so the answer to this question is : it doesn't, React only needs a function with on parameter( For better understanding of the work around you need know about javascript closure
in case you want to use currying
or javascript bind
function in case you're using binding )
Where is the contract for it?
you define in your code
Does the onClick function in the div expect a callback function where the second argument is the actual event?
No, It just need a function with one parameter, and in case it's confusing to you when using bind
function, just read bout it a little here
Where is this defined? it's one of the
class
parameter, and you need to read about it until you understand it (I recommend using Function Components so you don't need to work withthis
concept in javascript)
Upvotes: 0
Reputation: 6582
for your first question about passing event
you can do this:
export class ParentComponent extends React.Component<ParentComponentProps, ParentComponentState> {
public state: ParentComponentState = {
...
};
constructor(props) {
super(props);
}
private handleClick = (item) => (event) => { // This is called function currying
console.log(item);
console.log(event);
}
public render(): JSX.Element {
return (
<>
<SomeButtonComponent>
{ this.props.options.map((item: any, index: any) => (
<ChildComponent
onClick={ this.handleClick(item) }
/>
)) }
</SomeButtonComponent>
</>
);
}
}
and for your second question if you want to know in ChildComponent
that which options created it you have to pass another props to ChildComponent
and send the option
in ChildComponent
as a prop and use it there
Upvotes: 1