Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript and hooks

Could anyone advise me on the best way to convert this hook to a type safe version using Typescript please. Its a simple toggle to display a different 'thing' on toggle state.

useToggle.js

const useToggleButton = ({on,off}) => {
  const [toggle, setToggle] = React.useState(false)

  const ToggleButton = () => (
    <div
      role="button"
      onClick={() => setToggle(!toggle)}
      data-testid="portal-toggle-btn"
    >
      {toggle? on : off}
    </div>
  )
  return [ToggleButton, toggle, setToggle]
}

The thing is that it returns an array with the component, state and setState function. My attempt is below but I get the errors

TS2605: JSX element type 'IReturnType' is not a constructor function for JSX elements.   Type 'IReturnType' is missing the
following properties from type 'Element': type, props, key

TS2739: Type '(boolean | Dispatch<SetStateAction<boolean>>)[]' is
missing the following properties from type 'IReturnType': component,
state, func

useToggle.tsx

import * as React from 'react'

interface IToggleBntProps {
  on: any
  off: any
}

interface IState {
  bol: boolean
}

interface IReturnType {
  component: React.FunctionComponent
  state: boolean
  func: (bol: boolean) => IState
}

const useToggleButton = ({ on, off }: IToggleBntProps): IReturnType => {
  const [toggle, setToggle] = React.useState(false)

  const ToggleButton = () => (
    <div
      role="button"
      onClick={() => setToggle(!toggle)}
      data-testid="portal-toggle-btn"
    >
      {toggle ? on : off}
    </div>
  )
  return [ToggleButton, toggle, setToggle]
}

export default useToggleButton
like image 784
dorriz Avatar asked Jun 14 '19 04:06

dorriz


People also ask

What are hooks in TypeScript?

Benefits of TypeScript with Hooks Local state types are often inferred by the default state values. Components with hooks are all functions. So, we can write the same component returning the FC<P> type defined in the React library. The function explicitly declares its return type, setting along the props type.

What is TypeScript useEffect?

useEffect. useEffect is here for all side effects. Adding event listeners, changing things in the document, fetching data. Everything you would use component lifecycle methods for ( componentDidUpdate , componentDidMount , componentWillUnmount ) The method signature is pretty straightforward.

When should you not use hooks?

Don't call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function, before any early returns. By following this rule, you ensure that Hooks are called in the same order each time a component renders.

What are hooks in JavaScript?

Hooks are JavaScript functions that manage the state's behaviour and side effects by isolating them from a component. So, we can now isolate all the stateful logic in hooks and use (compose them, as hooks are functions, too) into the components.


1 Answers

TypeScript can actually figure out most of these types automatically!

In the code below, saying as const (a const assertion) at the end of your return statement lets TypeScript correctly infer the return type you want: [() => JSX.Element, boolean, React.Dispatch<React.SetStateAction<boolean>>].

If you wanted to be explicit, you could do type IReturnType = [() => JSX.Element, boolean, React.Dispatch<React.SetStateAction<boolean>>], but that's verbose and unnecessary.

interface IToggleBntProps {
  on: any
  off: any
}

const useToggleButton = ({ on, off }: IToggleBntProps) => {
  const [toggle, setToggle] = React.useState(false)

  const ToggleButton = () => (
    <div
      role="button"
      onClick={() => setToggle(!toggle)}
      data-testid="portal-toggle-btn"
    >
      {toggle ? on : off}
    </div>
  )

  // saying 'as const' here means that TypeScript automatically
  // knows that this should be a tuple type of three elements.
  // Not you need TypeScript 3.4 or newer 
  return [ToggleButton, toggle, setToggle] as const;
}

export default useToggleButton
like image 93
JKillian Avatar answered Oct 08 '22 13:10

JKillian