Reputation: 247
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
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