Shamoon
Shamoon

Reputation: 43491

How to set the proper type of a React Context?

I have:

interface AccountContextProps {
  accountInfo: AccountInfo | null;
  setAccountInfo: React.Dispatch<React.SetStateAction<AccountInfo | null>>;
  isAccountInfoLoading: Boolean;
}

const AccountContext = React.createContext<AccountContextProps>({
  accountInfo: null,
  setAccountInfo: () => undefined,
  isAccountInfoLoading: false,
});

const AccountProvider: React.FC = ({ children }) => {
  const [accountInfo, setAccountInfo] = useState(null);
  const [isAccountInfoLoading, setIsAccountInfoLoading] = useState(false);

  const fetchAccountInfo = async (accountApiUrl, authenticationSystem) => {
    initAccountClient(accountApiUrl, authenticationSystem);
    const accountInfoResponse: AccountInfo = await getAccountInfo();
    setAccountInfo(accountInfoResponse);
  };

But the setAccountInfo has a lint error:

Argument of type 'AccountInfo' is not assignable to parameter of type 'SetStateAction<null>'.ts(2345)

What am I doing wrong?

Upvotes: 0

Views: 73

Answers (1)

jsejcksn
jsejcksn

Reputation: 33693

Disregarding your fetchAccountInfo function (because you haven't provided enough info about it), this is how to correctly type the remaining code you've shown:

TS Playground

import {
  default as React,
  createContext,
  useState,
  type Dispatch,
  type ReactElement,
  type ReactNode,
  type SetStateAction,
} from 'react';

type AccountInfo = unknown;

interface AccountContextProps {
  accountInfo: AccountInfo | null;
  setAccountInfo: Dispatch<SetStateAction<AccountInfo | null>>;
  isAccountInfoLoading: Boolean;
}

const AccountContext = createContext<AccountContextProps>({
  accountInfo: null,
  setAccountInfo: () => undefined,
  isAccountInfoLoading: false,
});

const AccountProvider = ({ children }: { children?: ReactNode }): ReactElement => {
  const [accountInfo, setAccountInfo] = useState<AccountInfo | null>(null);
  const [isAccountInfoLoading, setIsAccountInfoLoading] = useState(false);

  // const fetchAccountInfo = async (accountApiUrl, authenticationSystem) => {
  //   initAccountClient(accountApiUrl, authenticationSystem);
  //   const accountInfoResponse: AccountInfo = await getAccountInfo();
  //   setAccountInfo(accountInfoResponse);
  // };

  return (
    <AccountContext.Provider value={{accountInfo, isAccountInfoLoading, setAccountInfo}}>
      {children}
    </AccountContext.Provider>
  );
};

Upvotes: 1

Related Questions