9

I have created a react typescript app with create react app. I now want to have a context which I want accessible across all my components:

export const UserContext = React.createContext<{name: string}>({name: 'Foo'});

The context is linked to the state of the main app component. This state does change and therefore the value of context should also change for the components.

<UserContext.Provider value={this.state}>
    <MainPage/>
</UserContext.Provider>

I have followed the doc string suggestion for how to set up in context in a component and so have this:

class MainPage extends React.Component {
   static contextType = UserContext;
   context!: React.ContextType<typeof UserContext>;

   public render() {
       return <div>{this.context.name}</div>
   }
}

However this.context.name is always null. I have placed a div with it's value linked to this.state in the app component and that does show the value unlike the context. I am struggling as the code works when written in raw react / create-react-app and I was under the components where the same in @types/react?

Does anyone know how to implement context inside a component class in typescript?

1
  • @types/react doesn't behave differently. It has no runtime behaviour it is just a declaration file that is used to statically check the code for errors. Commented Dec 1, 2018 at 22:43

1 Answer 1

28

Looks like the type parameter of your UserContext is slightly wrong. You need to remove the typeof.

so React.createContext<{ name: string }> instead of React.createContext<typeof { name: string }>

This works for me:

import * as React from 'react';

const UserContext = React.createContext<{ name: string }>({ name: 'test' });

export class MainPage extends React.Component<undefined, undefined> {
  static contextType = UserContext;
  context!: React.ContextType<typeof UserContext>;

  public render() {
    return <div>{this.context.name}</div>;
  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

That is correct that there should not be a typeof in front of the interface. I made that mistake when writing this question because I was simplifying a more complex interface that actually exists there. So having removed the typeof the context still doesn't work??? However if I copy your code above my reactapp does not compile as it does not like the export infront of the class without a default keyword AND it also does not like the undefined as type arguments of type arguments. What version are you using as my version may not like context?
what errors are you getting? are they typescript errors, or lint errors
i was just doing it on codesandbox, just checked that the types worked, but didnt go further than that
for ts 3.7 and above it should be done like this static contextType = SampleContext; declare context: ContextType<typeof SampleContext>
Using declare seems to require a babel transformation (TypeScript 'declare' fields must first be transformed by @babel/plugin-transform-typescript), which I don't currently include in my package, nor do I want to for my very-infrequent class-usage. I'm going to stick to the context! method, personally.

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.