0

I'm trying to refactor my context to use a custom hook in TypeScript and I've got an error I don't know how to fix.

This is the error:

This expression is not callable. Not all constituents of type 'boolean | Dispatch<SetStateAction>' are callable. Type 'false' has no call signatures. TS2349

My custom hook is defined like this:

export const useOfflineContext = () => {
  const isOffline = React.useContext(OfflineContext);
  const setIsOffline = React.useContext(OfflineSetContext);

  if (!setIsOffline) {
    throw new Error('The OfflineProvider is missing.');
  }
  return [isOffline, setIsOffline];
};

And I'm calling it like this:

  const [setIsOffline] = useOfflineContext();

  // Check if we are online or offline.
  useEffect(() => {
    Network.addListener('networkStatusChange', (networkStatus) => {
      // console.log('Network status changed', networkStatus);
      if (!networkStatus.connected) {
        setIsOffline(true);

This causes the error above.

Here's my full component OfflineContextProvider.tsx:

import React, { useState } from 'react';

const OfflineContext = React.createContext(false);
const OfflineSetContext = React.createContext({} as React.Dispatch<React.SetStateAction<boolean>>);

interface MyProps {
  children: JSX.Element,
}

export const OfflineContextProvider: React.VFC<MyProps> = ({ children }: MyProps) => {
  const [isOffline, setIsOffline] = useState<boolean>(false);

  return (
    <OfflineContext.Provider value={isOffline}>
      <OfflineSetContext.Provider value={setIsOffline}>
        {children}
      </OfflineSetContext.Provider>
    </OfflineContext.Provider>
  );
};

export const useOfflineContext = () => {
  const isOffline = React.useContext(OfflineContext);
  const setIsOffline = React.useContext(OfflineSetContext);

  if (!setIsOffline) {
    throw new Error('The OfflineProvider is missing.');
  }
  return [isOffline, setIsOffline];
};

I don't understand why, when I specifically ask for const [setIsOffline] = useOfflineContext();, TypeScript thinks that I might want isOffline instead. (Because the TypeScript warning mentions the boolean value (isOffline).)

So my question is: How can I properly type useState when used in a custom hook to return a context?

Currently using TypeScript 4.3.

1 Answer 1

2

You're using the first element of the returned array, which is isOffline (a boolean), but you're calling it setIsOffline. However, it is still a boolean.

What you probably want is to get the second element of the array:

const [ , setIsOffline ] = useOfflineContext();
Sign up to request clarification or add additional context in comments.

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.