user14899645
user14899645

Reputation:

Using useContext in a pure Typescript class

I am having a pure Typescript class that does a homogenous activity as a utility class. I have created a context that can be used anywhere, and I wanted to know if we could use this context and its values in a pure Typescript class.

The class looks like this:

export class UtilityClass {
    public async method1() {
        ...
    }
    public async method2() {
        ...
    }
}

I would like to use the Context like this:

const { total, cartItems } = useContext(CartContext);

I have tried by creating a static context type like this in the class:

export class UtilityClass {
    static contextType = CartContext
    public async method1() {
        const { total, cartItems } = useContext(CartContext);
        ...
    }
    public async method2() {
        ...
    }
}

But this is throwing following error:

any
Property 'context' does not exist on type 'UtilityClass'.

Upvotes: 2

Views: 2009

Answers (2)

Nicholas Tower
Nicholas Tower

Reputation: 84902

Context is integrally tied in to the react component tree. When a component tries to access context (either via useContext in a function component, or various methods in a class component), react looks up the tree to find the nearest context provider. So the placement of your component in the tree relative to any providers is crucial for determining what value you get.

As a result, it's nonsensical to try to access context outside a component. If you're not in a component, then there's no hierarchy of components above you to access. Depending on what you're trying to do, there's a couple possibilities:

  1. If the value you're trying to share is a global value that's not really related to the component tree, you could remove it from the components entirely. The value can be exported from a file, and imported wherever it is needed. This is easy if the value never changes, but if it does change then components will not automatically rerender. So you may need to set up some way of notifying components of the change, at which point the components set state and rerender themselves.

  2. Another option is that you can write your utility functions so that you pass in the values that you need. The component that uses the function will be responsible for listening to context, and then when it calls the utility function it passes those values in.

const SomeComponent = () => {
  const { total, cartItems } = useContext(CartContext);
  useEffect(() => {
    new UtilityClass().method1(total, cartItems);
  }, []);
    ...
}

export class UtilityClass {
    public async method1(total, cartItems) {
        ...
    }

Upvotes: 4

Zhang TianYu
Zhang TianYu

Reputation: 1195

Impossible. You can access context in class that extends React.Component, And the child of Context Provider.

Upvotes: 1

Related Questions