Josip Marić
Josip Marić

Reputation: 247

Typescript/Javascript custom hooks

i am beginner and trying to refactor Javascript hooks into Typescript but i cannot get button onClick event to change state. Can you please help?

This is useToggler component

import {useState} from 'react'

function useToggler (defaultOnValue=false){
    const[istoggledOn, setIsToggledOn] = useState(defaultOnValue);

    function clickHandler(){
        setIsToggledOn(prevState => !prevState)
    }

    return [istoggledOn, clickHandler]
}

export default useToggler

and this is App component

import * as React from 'react';
import './App.css';
import useToggler from './compononets/useToggler'




const App: React.FC = () => {
    const[show, toggle]=useToggler(true);

    return (
        <div className="App">
            <button onClick={()=>toggle}>+</button>
            <span>{show? "yes!": "no!"}</span>
        </div>
    );

};

export default App;


Upvotes: 0

Views: 323

Answers (1)

Dan
Dan

Reputation: 10548

You're getting a type error because you're returning an array in your useToggler function.

function useToggler (defaultOnValue=false){
    const[istoggledOn, setIsToggledOn] = useState(defaultOnValue);

    function clickHandler(){
        setIsToggledOn(prevState => !prevState)
    }

    return [istoggledOn, clickHandler] // Here
}

TypeScript interprets your return statement as meaning that you have an array of either boolean or () => void. This means that your toggle variable is identified as being of type boolean | (() => void) rather than () => void, hence the error message:

Not all constituents of type 'boolean | (() => void)' are callable

You resolve this by explicitly telling TypeScript that, no, you're not returning an array of T | K but rather a tuple of T and K. You could write out the type yourself, but newer versions of TypeScript can use as const to do this:

function useToggler (defaultOnValue=false){
    const[istoggledOn, setIsToggledOn] = useState(defaultOnValue);

    function clickHandler(){
        setIsToggledOn(prevState => !prevState)
    }

    return [istoggledOn, clickHandler] as const
}

Upvotes: 1

Related Questions