In my component, I have:
<StyledPill
key={`styled-pill-${idx}`}
size="small"
label={searchType.label}
onClick={() => handleClick(idx 1)}
featured={selectedSearchType === idx 1}
/>
where:
const handleClick = (index: number) => {
setSelectedSearchType(index);
};
However, I was told that we don't want to have anonymous functions () => handleClick(idx 1)
. Is there some performant way to avoid it?
I can't do onClick={handleClick}
because then I can't pass the argument.
Looking for some help - any would be appreciated. Thanks!
CodePudding user response:
You can avoid creating an anonymous handler for each element by making the per-item data available on the element, and reading it in the event handler.
However, this is a premature optimization that you probably don't need.
function Component({ searchTypes, selectedSearchType, handleClick }) {
const handleItemClick = React.useCallback((event) => {
const itemId = parseInt(event.target.dataset.index);
handleClick(itemId);
}, [handleClick]);
return (
<>
{searchTypes.map((searchType, idx) => (
<StyledPill
key={`styled-pill-${idx}`}
size="small"
label={searchType.label}
data-index={idx 1}
onClick={handleItemClick}
featured={selectedSearchType === idx 1}
/>
))}
</>
);
}
CodePudding user response:
Hmm, if you really would like to do it and have access to the StyledPill
component, an option could be to accept onClick
and index
as props, then write a wrapper function to call the onClick
with the index
.
<StyledPill
key={`styled-pill-${idx}`}
size="small"
label={searchType.label}
onClick={handleClick}
index={idx 1}
featured={selectedSearchType === idx 1}
/>
// StyledPill.jsx
function StyledPill({onClick, index}) {
function handleOnClick() {
onClick(index);
}
return (
<button onClick={handleOnClick} .../>
)
}
CodePudding user response:
If you just want to pass a named function to the onClick
handler you could define the function inside your map()
callback:
function Component({ searchTypes, selectedSearchType, handleClick }) {
const handleClick = (index: number) => {
setSelectedSearchType(index);
};
return (
<>
{searchTypes.map((searchType, idx) => {
const handlePillClick = () => handleClick(idx 1);
return (
<StyledPill
key={`styled-pill-${idx}`}
size="small"
label={searchType.label}
data-index={idx 1}
onClick={handlePillClick}
featured={selectedSearchType === idx 1}
/>
);
})}
</>
);
}
CodePudding user response:
You could achieve that like this, which is also called point-free style
const handleClick = (index: number) => () => {
setSelectedSearchType(index);
};
// ...
<StyledPill
key={`styled-pill-${idx}`}
size="small"
label={searchType.label}
onClick={handleClick(idx 1)}
featured={selectedSearchType === idx 1}
/>
Codesandbox Demo