4

I wrote custom hook for toggling booleand valuse:

import { useState } from 'react';

export function useToggle(initialValue: boolean) {
  const [value, setValue] = useState<boolean>(initialValue);

  const toggleValue = () => setValue(!value);

  return [value, toggleValue];
}

Then I use it like below:

 const [modalOpen, setModal] = useToggle(false);

But get errors:

Type 'boolean | (() => void)' is not assignable to type 'boolean | ((() => void) & false) | ((() => void) & true)'. Type '() => void' is not assignable to type 'boolean | ((() => void) & false) | ((() => void) & true)'. Type '() => void' is not assignable to type '(() => void) & false'. Type '() => void' is not assignable to type 'false'.

1
  • I was just working on the same thing. This is a great article fettblog.eu/typescript-react-typeing-custom-hooks You need to return [value, toggleValue] as const or add a return type to the useToggle function do return a tuple not an array Commented Oct 15, 2021 at 18:20

3 Answers 3

5

You might need to define the return type of your hook. It should look something like this.

import { useState } from 'react';

export function useToggle(initialValue: boolean): [boolean, () => void] {
  const [value, setValue] = useState<boolean>(initialValue);

  const toggleValue = () => setValue(!value);

  return [value, toggleValue];
}
Sign up to request clarification or add additional context in comments.

Comments

1

const {useRef, useState} = React;

function useToggle(initialState){
  const [value, setValue] = useState(initialState);
  const toggle = () => { setValue(!value) };
  
  return [value, toggle];
};

function App(){
  const [modal, setModal] = useToggle(false);
  return (
    <div>
      <button onClick={setModal}>Toggle!</button>
      {modal && <span>Toggle!!!!</span>}
    </div>
  )
}

ReactDOM.render(
  <App />, document.getElementById('root')
)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>

4 Comments

what do these scripts do? Why do we need them?
That is React as CDN! You don't need to care about that, you just see the code about yours
but you didnt change anything, errors are still there
@heisenberg7584 I've just wrapped toggle() with {}. did you wrap like it?
0

For any future reference, I think this solution is more accurate, considering the fact that multiple calls to this hook or calling it from useEffect can provide the wrong value.

export function useToggle(initialValue: boolean = false): [boolean, () => void] {
  const [isOpen, setIsOpen] = useState<boolean>(initialValue);
  const toggleChange = (()=>{
      setIsOpen(prev => !prev)
  })  
  return [isOpen, toggleChange]
}

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.