0

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>
  );
}
BEDev
  • 699
  • 1
  • 5
  • 9
  • Does this answer your question? [How to pass data from child component to its parent in ReactJS?](https://stackoverflow.com/questions/38394015/how-to-pass-data-from-child-component-to-its-parent-in-reactjs) –  Jul 27 '20 at 21:46

2 Answers2

1

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>
  );
}
Tyler Watts
  • 173
  • 4
0

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>
mttetc
  • 711
  • 5
  • 12