0

I'm a bit new to TypeScript, but I LOVE it.

When I try to destructure my Context in React using useContext I get some errors that I don't know why I'm getting.

The error: Property 'nftContract' does not exist on type 'Web3 | null'.ts(2339)

Context File

export interface Web3 {
  gameContract: Contract | string;
  nftContract: Contract | string;
  provider: Provider | string;
  account: string;
  etherBalance: string;
  setWeb3?: React.Dispatch<React.SetStateAction<Web3>>;
}

export const Web3Context = createContext<Web3 | null>(null);

export const Web3Provider: React.FC = ({ children }) => {
  const [
    { gameContract, nftContract, provider, account, etherBalance },
      setWeb3
    ] = useState<Web3>({
      gameContract: '',
      nftContract: '',
      provider: '',
      account: '',
      etherBalance: ''
  });

  return (
    <Web3Context.Provider
        value={{
            provider,
            gameContract,
            nftContract,
            account,
            etherBalance,
            setWeb3
        }}
    >
        {children}
    </Web3Context.Provider>
  );

File consuming Context (Context has been wrapped properly in the main index/app file.)

const MintNFTForm = () => {
   // Property 'nftContract' does not exist on type 'Web3 | null'.ts(2339)
   const { nftContract } = useContext(Web3Context);
}

Anything helps,thank you!

1 Answer 1

3

Destructure the value only after it has been checked for not being null:

const MintNFTForm = () => {
   const ctxt = useContext(Web3Context);
   if (ctxt == null) return <div>No context yet</div>;

   // `ctxt` is now guaranteed to not be `null`, safe to destructure
   const { nftContract } = ctxt;
}

The code is initializing the context's value to null and declaring that its type can be null so any code referencing it must account for that case:

export const Web3Context = createContext<Web3 | null>(null);
Sign up to request clarification or add additional context in comments.

7 Comments

Oh awesome, thank you! I'll try this. How can I set the createContext value to be empty? I would like for it to not have the value null & just the Web3, but I also would like to not pass anything to createContext. Is there a way to leave it blank? When I try to leave it blank it complains that it needs to be passed in 1 arguement.
The error I get if I change it to export const Web3Context = createContext<Web3>(); is: Expected 1 arguments, but got 0.ts(2554) index.d.ts(383, 9): An argument for 'defaultValue' was not provided.
I would also like to be able to restructure the context without having to check for null since it'd be a lot cleaner to do so.
What is a Web3? Is there a default Web3 you can pass to createContext? "Cleaner" is a subjective term here; checking for null is correct since the value is initialized to null, this looks clear to me!
Web3 is something in Blockchain. Based on your example: what if I wanted to not return anything because my component has other stuff it needs to render?
|

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.