programmingfun
programmingfun

Reputation: 97

onClick event on child component that already has a onClick event?

My first component looks like this:

export default function Overview() {
  const selectPlantHandler = () => {
    console.log("add to selection");
  }

  return (
        <div>
          {plants.map((element, index) => {
            return (
              <PlantCard key={index} 
                         onClick={selectPlantHandler}>
                 Herbert
              </PlantCard>
            );
          })}
        </div>
  );
}

My second component "PlantCard" that I call in my first component looks like this:

export default function PlantCard({ children } : { children: any }) {
  const [isActive, setIsActive] = useState(false);

  function onClickHandler() {
    setIsActive(!isActive);
  }

  return (
    <div onClick={onClickHandler} isActive={isActive}>
        <h3>{children}</h3>
    </div>
  );
}

I have several PlantCard components in my parent component. I want to select them when clicking on them. But I get the following error message:

Type '{ children: string; key: number; onClick: () => void; }' is not assignable to type 'IntrinsicAttributes & { children: any; }'. Property 'onClick' does not exist on type 'IntrinsicAttributes & { children: any; }'.

I have found some solutions, but in none of these had the child component a onClick function. So how can I fix the issue for this specific case?

Upvotes: 1

Views: 683

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 371168

Add an onClick prop to PlantCard so you can pass it down as a prop. Best to type the childen prop properly as well - any effectively defeats the purpose of using TypeScript in the first place.

When rendering, one option is to call the prop inside the onClickHandler.

export default function PlantCard({ children, onClick }: { children: JSX.Element, onClick: () => void }) {
    const [isActive, setIsActive] = useState(false);
    function onClickHandler() {
        setIsActive(!isActive);
        onClick();
    }
    return (
        <div onClick={onClickHandler}
        isActive={isActive}>
            <h3>{children}</h3>
        </div>
    );
}

Another option have the click handler be an inline function that calls both onClickHandler and the prop click handler.

<div onClick={() => { onClickHandler(); onClick(); }}

Upvotes: 1

Related Questions