Reputation: 1184
In React, when to use a function in Props?
For example in the code below sometimes you don't use a function in prop, but sometimes you do.
import React, { useState } from 'react';
const IterationSample = () => {
const input = React.createRef();
const [names, setNames] = useState(
[
{ id: 1, text: 'John' },
{ id: 2, text: 'Jake' },
{ id: 3, text: 'JJ' },
{ id: 4, text: 'Jesus' }
])
const [inputText, setInputText] = useState('');
const [nextId, setNextId] = useState(5);
const onChange = e => setInputText(e.target.value);
const onRemove = id => {
const nextNames = names.filter(name => name.id !== id);
setNames(nextNames);
}
const namesList = names.map(name => <li key={name.id} onDoubleClick={() => onRemove(name.id)}>{name.text}</li>);
const onClick = () => {
const nextNames = names.concat({
id: nextId,
text: inputText
});
setNextId(nextId + 1);
setNames(nextNames);
setInputText('');
input.current.focus();
}
const onEnter = (e) => {
if (e.key === 'Enter') {
onClick();
}
}
return (
<>
<input ref={input} value={inputText} onChange={onChange} onKeyPress={onEnter} />
<button onClick={onClick} >Add</button>
<ul>{namesList}</ul>
</>
);
};
export default IterationSample;
Here you use ()=> a function in onDoubleClick={() => onRemove(name.id)
but, not either in onKeyPress={onEnter}
or onChange={onChange}
So when do you use a function in props?
Upvotes: 0
Views: 581
Reputation: 576
Just to clarify, since it seems like you may not be getting quite the beginner-friendly answer that you're looking for:
Something like "onKeyPress" or "onChange" comes with an implicit event. What does that mean? It means that whatever function you tie into that component, it will be triggered with an "event," and that will be the argument of any function that you feed in. In fact, if you look at the functions themselves, you'll notice that they accept an argument, 'e' for event. So, if it helps, you can think of some of those commands as saying
onKeyPress={()=>onEnter(keyPressEvent)}
The events will have some useful data in them, but typically the only thing that we'll care about is something like which key the user pressed, or (in the event of a change) what the new content of an input is.
For something like onDoubleClick, you're giving it some extra data. You can do some fancy footwork with javascript to identify what was double clicked and what its attributes were, but that's a pain in the butt, adds unnecessary code, and tends to obfuscate your intent in whatever it is you were coding. So it's ultimately easier to just feed the function whatever you want it to have.
Upvotes: 1
Reputation: 83
:)
David and Ertan answer are really good and complete. I will just add two more things.
First, considering reactjs good practice and perfomance do not use arrow function in render.
According to eslint rules eslint rules :
A bind call or arrow function in a JSX prop will create a brand new function on every single render. This is bad for performance, as it may cause unnecessary re-renders if a brand new function is passed as a prop to a component that uses reference equality check on the prop to determine if it should update.
Secondly in the case you need to customize what you're passing to the function (in this case on Remove
) you can use an alternative from lodash : partial
the official doc
Here an exemple with your code :
const namesList = names.map(name =>
<li key={name.id}
onDoubleClick={ _.partial(this.onRemove, name.id)}
>
{name.text}
</li>
);
have a good day
Upvotes: 1
Reputation: 3644
This
onClick={onClick}
is equivalent to
onClick={(e) => onClick(e)}
For the first case, you are passing the function itself as the props.
For the second case, you are defining an inline function that calls onClick
function with the parameter (e)
.
Generally you can just pass the function itself as the props unless you want to add additional parameters when calling your function. For example,
onClick={(e) => onClick(e, name.id)}
Upvotes: 1
Reputation: 1773
You basically use it when you need to pass extra paremeters (except event
itselft).
ex. when you want to pass id
in your case you do:
onClick={(e) => onRemove(name.id)}
//or together with the event
onClick={(e) => onRemove(e, name.id)}
Otherwise when you dont need to pass a parameter inside a function, or you only need to pass event
you can write it like:
onClick={onRemove}
Upvotes: 2
Reputation: 218837
All three of your examples use a function:
onDoubleClick={() => onRemove(name.id)}
onKeyPress={onEnter}
onChange={onChange}
The only difference is that one of them needs to specify an argument to the function (onRemove
), whereas the other two do not.
If the arguments being passed by the property (in this case onKeyPress
and onChange
) are exactly what the function needs, then you just reference the function as-is. But if you need to customize what you're passing to the function (in this case onRemove
), you can wrap it in a new function to enclose that customization.
Upvotes: 3