简体   繁体   中英

How do I use a Consumer in a React app with TypeScript?

I have a React Component defined as follows:

import React from 'react';
import { AuthUserContext } from '../Session';

const Account = () => (
  <AuthUserContext.Consumer>
    {
      authUser => {
        return(
        <div>
          <h6 className="accountInfo"><strong>Account:</strong> {authUser.email} </h6>
        </div>
        )
      }
    }
  </AuthUserContext.Consumer>
);

export default Account;

This throws the error Object is possibly 'null' referring to the use of authUser.email in the line with h6.

Even if I do this:

authUser  ? <h6 className="accountInfo"><strong>Account:</strong>
              {authUser.email}
              </h6>
          : null

it still gives the same error.

When authUser is defined in withAuthentication , its value is initially set to null, but I thought that adding in the check for authUser would ensure that it was never null when it hit authUser.email .

What am I doing wrong?

This behavior could have been caused by missing braces around the conditional expression, but instead it was because of a combination of a null context type and an inaccurate TypeScript error.

If the context is created like this

const context: {email: string} | null = null
const AuthUserContext = React.createContext(context)

TypeScript will infer type React.Context<null> , because the type of context is narrowed to null . Normally this would just cause a missing property error on usage, but TypeScript appears to have an issue with error messages for null constants in conditonal expressions inside closures.

In the code below ( playground ), weird yields an Object is possibly 'null' error on o , whereas nonWeird yields a proper error message.

const o = null
const weird = () => o ? o.p : '' // Error: Object is possibly 'null'.
const notWeird = o ? o.p : '' // Error: Property 'p' does not exist on type 'never'.

This explains the strange error message on authUser.email . The root problem can be fixed by providing a type parameter to createContext :

const React.createContext<{email: string} | null>(null)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM