stack_overflow
stack_overflow

Reputation: 137

What types to add for methods using react and typescript?

i want to add types to methods passed as props from parent to child component using react and typescript.

below is my code,

function Parent() {
    const [isClicked, setIsClicked] = React.useState(false);
    return (
        <Child setIsClicked={setIsClicked} >
            <div> somediv</div>
        </Child>
    );
 }

 interface Props {
     setIsClicked: any; //instead of any what type should be used here
 }
 function Child ({setIsClicked, children}: Props) {
     return (
         <div onClick={setIsClicked}>
             {children}
         </div>
     );
  }

As you see from above code, i am using any as type for setIsClicked method. this works. but i know that this is not the right way to do it.

could someone help me with this. thanks.

Upvotes: 0

Views: 413

Answers (3)

Karol Majewski
Karol Majewski

Reputation: 25790

That's how I would do it:

const Parent: React.FunctionComponent = () => {
  const [isClicked, setIsClicked] = React.useState(false);

  const handleClick = React.useCallback(() => {
    setIsClicked(true)
  }, []);

  return (
    <Child onClick={handleClick}>
      <div> somediv</div>
    </Child>
  );
}

interface Props {
  onClick: React.UIEventHandler<HTMLDivElement>
}

const Child: React.FunctionComponent<Props> = ({ onClick, children }) => {
  return (
    <div onClick={onClick}>{children}</div>
  )
}
  • handleClick is a generic click handler. No coupling to React hooks. The caller (Parent) can do whatever it chooses when the Child is clicked.
  • ✅ The Parent receives the event object, but is free to discard it. In this scenario the event object is discarded, but the Child willingly exposes it — it doesn't know how it's going to be used, which is desirable.
  • handleClick is memoized thanks to React.useCallback

Upvotes: 1

kind user
kind user

Reputation: 41893

The setter function accepts a value or a callback function which may complicate things a little bit. What I would suggest is to create a separate function to handle the onclick instead of passing the setter directly. It's more readable and cleaner.

Also remember to use the generic type when using useState hook.

function Parent() {
   const [isClicked, setIsClicked] = React.useState<Boolean>(false);
   const handleClick = (value: boolean) => {
      setIsClicked(value);
   };
   
   return (
      <Child setIsClicked={handleClick}>
          <div>somediv</div>
      </Child>
   );
}

interface Props {
    setIsClicked: (value: boolean) => void;
}

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 370679

The most precise type for that a setter function for type T is:

React.Dispatch<React.SetStateAction<T>>,

So you can do:

setIsClicked: React.Dispatch<React.SetStateAction<Boolean>>

But that's a bit wordy and sometimes requires import boilerplate you don't want. Often, denoting the type as a plain function that accepts the type as an argument is sufficient:

setIsClicked: (newClicked: boolean) => void

Upvotes: 2

Related Questions