1

I am trying to create a global state using a combination of useState with useContext in react using typescript.

#store.tsx

export const StoreContext = React.createContext();

export const StoreProvider = (({ children }: ChildrenType) => {
  const [test] = React.useState(['world']);

  const store = {
    test,
  };

  return <StoreContext.Provider value={store}>{children}</StoreContext.Provider>;
});
#app.tsx

import type { AppProps } from 'next/app'
import { StoreProvider } from '../store';

export default function App({ Component, pageProps }: AppProps) {
  return (
    <StoreProvider>
      <Component {...pageProps} />
    </StoreProvider>
  )
}
#index.tsx

import React from 'react';
import { StoreContext } from '../store';

export default function Home() {
  const { test: [test] } = React.useContext(StoreContext);

  return (
    <div>
      <h1>
        hello
        {test}
      </h1>
    </div>
  );
}

Now this works fine when I run in development mode (in this case npm run dev) however when I try and build it I get the following error:

$npm run build

> [email protected] build
> next build

info  - Linting and checking validity of types .Failed to compile.

./pages/index.tsx:7:11
Type error: Property 'test' does not exist on type 'unknown'.

   5 |
   6 | export default function Home() {
>  7 |   const { test: [test] } = React.useContext(StoreContext);
     |           ^
   8 |
   9 |   return (
  10 |     <div0

I have created a POC that contains this example here: https://github.com/jamesla/state-poc

How can I make this work?

1
  • This is a type error. There is no type information on the context. Try useContext<ISomeInterface>(initialState); Commented Nov 8, 2022 at 2:23

1 Answer 1

1

You haven't assigned a type to your context nor you have provided a value createContext(). So, typescript doesn't know what type the context will be. By default, it will be unknown.

You need to give a type to your context. You can do it like the following if it is going to be a string array and also pass the default value, if you want to avoid null checks.

export const StoreContext = createContext<Array<string>>([])

I recommend you to check out this blog post so that you don't have to re-invent any patterns.

Also, if you plan to use context as a global state, remember that it is not ideal for state that changes frequently. You should check out making react context fast, which is another pattern to improve the performance.

Sign up to request clarification or add additional context in comments.

3 Comments

Hmm i've tried this export const StoreContext = createContext<Array<string>>([]) and it does the same thing
I think the problem is related to this line const { test: [test] } = React.useContext(StoreContext); since the key test or array value test doesn't necessarily exist?
Since the context is an array, instead of passing store object value={store}, you should pass the array itself, like this: value={test} and your useContext would look like this: const context = React.useContext(StoreContext) and context[0] will be world

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.