7

I have this code for a component:

Feedback.tsx

import React, { useState } from 'react';
import './Feedback.css';

import FeedbackButton from './FeedbackButton';

function Feedback() {
  const [isOpen, setIsOpen] = useState<boolean>(false)

  return (
    <div className="Feedback">
      <FeedbackButton onClick={() => setIsOpen(!isOpen)} />
    </div>
  );
}

export default Feedback;

The FeedbackButton component looks like this:

FeedbackButton.tsx

import React from 'react';
import feedbackicon from './feedback.svg';
import './Feedback.css';

function FeedbackButton() {
  return (
    <button className="Feedback-button" type="button">
      <img src={feedbackicon} className="Feedback-button-icon" alt="feedback" />
    </button>
  );
}

export default FeedbackButton;

On the line <FeedbackButton onClick={() => setIsOpen(!isOpen)} /> I get the error Type '{ onClick: () => void; }' is not assignable to type 'IntrinsicAttributes'. Property 'onClick' does not exist on type 'IntrinsicAttributes'.

I searched it up and tried to fix it using FunctionalComponent, but I got the same error. How can I make this onClick with useState work?

2 Answers 2

12
function FeedbackButton(props:{onClick:()=>void}) {
  return (
    <button className="Feedback-button" type="button" onClick={props.onClick}>
      <img src={feedbackicon} className="Feedback-button-icon" alt="feedback" />
    </button>
  );
}

something like this should work for you even better you can copy the type from button onclick to your props and have better typing if needed

Sign up to request clarification or add additional context in comments.

2 Comments

Perfect thank you. Is this a good and clean way to handle this, or is there, in your opinion, a more best practise way of handling such things
when i have components in my project, i try to keep the props small, usually create an interface called Props, unless you are creating a library that can be used in many different ways, that case you'll probably extend your Props interface from the Button Props, which looks like this React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>. when you extend from button props, you also need to pass those props down to button as well. you can find more info about the props in react typings, hope that helps
0

@tonakai fixes the problem well!

However, very often, the onClick logic is "owned" by the parent, and it is more natural to not have the child "know" anything about clicks that the parent is managing.

For example, when you have a child component which is implemented in multiple places, and only some places require the onClick.

So I sometimes wrap it like

<div onClick=...>
  <CustomComponent></CustomComponent>
</div>

This has the disadvantage of adding an extra div in the DOM, but can be worth it for component de-coupling.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.