Reputation: 178
consider the following example...
I have a component called ChemVisualisation.jsx it is as follows
const ChemVisualization = props => {
const { getChemists, chemists } = props;
useEffect(() => {
getChemists();
}, [getChemists]);
// useState hook is used here
// handleChange sets the name property
// i check for chemists based on name property here and pass it as props to
// SearchableDropdown component where it renders the list
const getChemistId = id => {
console.log(id);
// showing undefined
};
return(
<SearchableDropdown
getName={ChemistAnalytics}
onChange={e => handleChange(e)}
name="name"
value={name}
onSubmit={e => handleSubmit(e)}
entities={result}
handleClick={getChemistId}
/>
);
}
SearchableDropdown.jsx
const SearchableDropdown = props => {
// destructure props here
return(
<div className="control has-icons-left w-3/5 ">
<input
type="text"
placeholder="search"
value={value}
name={name}
onChange={onChange}
className="input"
autoComplete="off"
/>
<span className="icon is-left">
<FontAwesomeIcon icon={faSearch}></FontAwesomeIcon>
</span>
</div>
{entities && (
<div className="dropdown">
<div className="dropdown-content">
{entities.map(r => (
<div
className="dropdown-item text-xl hover:bg-gray-400 w-full"
key={r._id}
onClick={r => handleClick(r._id)}
>
{r.chem_name}
</div>
))}
</div>
</div>
)}
);
}
When I click the drop down item, I'm not getting the id in its parent component.
My question is how do I get the id of the drop down item that I clicked? Is passing the data from child component to its parent an anti-pattern?
Upvotes: 0
Views: 308
Reputation: 1075427
It's normal for child components to call functions their parents provide to them in response to events. The parent then rerenders as necessary with the new information. This keeps the state information fairly "high." More in Lifting State Up in the documentation.
In your example with
<div className="dropdown-content">
{entities.map(r => (
<div
className="dropdown-item text-xl hover:bg-gray-400 w-full"
key={r._id}
onClick={r => handleClick(r._id)}
>
{r.chem_name}
</div>
))}
</div>
the problem is that you're shadowing r
(the parameter of the map
callback) with a different r
(the parameter of the onClick
). The first argument the click handler is called with is an event object. If you don't want it, just don't accept the parameter:
<div className="dropdown-content">
{entities.map(r => (
<div
className="dropdown-item text-xl hover:bg-gray-400 w-full"
key={r._id}
onClick={() => handleClick(r._id)}
>
{r.chem_name}
</div>
))}
</div>
The only change there is replacing r
with ()
in onClick={() => handleClick(r._id)}
.
Upvotes: 1