Reputation: 739
I have a list of Child objects mapped from my Parent component in my React App.
When a Child item is clicked, I need the props.name of that item to be pushed to the selectedItems array in the Parent component via the handleClick function.
How can I achieve this?
function Parent() {
let selectedItems = [];
const result = Data.filter((e) => selectedItems.includes(e.id));
return (
<div className="App">
<main className="products-grid flex flex-wrap">
{Data.map((item, i) => {
return <Child
key={item.id}
name={item.name} />
})}
</main>
</div>
);
}
export default App
const Child = (props) => {
const [clickCount, setClickCount] = useState(0);
function handleClick() {
setClickCount(prevClickCount => prevClickCount + 1);
}
return (
<div
className="product"
onClick={() => handleClick()}
>
<p>{props.name}</p>
<p>{clickCount > 0 ? <p>Selected: {clickCount}</p> : <p>Not Selected</p>}</p>
<img src={props.img} alt="" />
</div>
);
}
Upvotes: 0
Views: 104
Reputation: 193
I would recommend using hooks for the 'selectedItems' in the parent component, as to trigger a re-render when the name changes.
You can pass functions from the parent to the child component using props.
Below I've passed the 'addToSelectedItems' function down to the child and triggered it in the handleClick method.
const Parent = () => {
const [selectedItems, setSelectedItems] = useState([]);
function addToSelectedItems(name){
setSelectedItems([...selectedItems, name]);
}
return (
<div className="App">
<main className="products-grid flex flex-wrap">
{Data.map((item, i) => {
return <Child
key={item.id}
name={item.name}
addToSelectedItems={addToSelectedItems}
/>
})}
</main>
</div>
);
}
export default App
const Child = (props) => {
const [clickCount, setClickCount] = useState(0);
function handleClick(name) {
setClickCount(prevClickCount => prevClickCount + 1);
props.addToSelectedItems(name);
}
return (
<div
className="product"
onClick={(props.name) => handleClick(props.name)}
>
<p>{props.name}</p>
<p>{clickCount > 0 ? <p>Selected: {clickCount}</p> : <p>Not Selected</p>}</p>
<img src={props.img} alt="" />
</div>
);
}
Upvotes: 1
Reputation: 745
I'd do something like this, but I have not tested it, it might need some fine tuning
function Parent() {
let selectedItems = [];
const result = Data.filter((e) => selectedItems.includes(e.id));
const [clickCount, setClickCount] = useState(0);
function handleClick(name) {
setClickCount(prevClickCount => prevClickCount + 1);
selectedItem.push(name)
}
return (
<div className="App">
<main className="products-grid flex flex-wrap">
{Data.map((item, i) => {
return <Child
key={item.id}
name={item.name}
clickCount={clickCount}
handleClick={handleClick} />
})}
</main>
</div>
);
}
export default App;
const Child = (props) => {
let { handleClick, name, clickCount, img } = props
return (
<div
className="product"
onClick={() => handleClick(name)}
>
<p>{name}</p>
<p>{clickCount > 0 ? <p>Selected: {clickCount}</p> : <p>Not Selected</p>}</p>
<img src={img} alt="" />
</div>
);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Upvotes: 0