skip to Main Content

I’m trying to set an Array of objects (users) as state in my Next app using context.

Here is the code:

import React, {
  Dispatch,
  SetStateAction,
  createContext,
  useState,
  useEffect,
} from "react";

type Props = {
  children: JSX.Element;
};

type User = {
  _id: string;
  firstname: string;
  lastname: string;
};

type ContextValue = [User[], Dispatch<SetStateAction<User[]>>];

export const UserContext = createContext<ContextValue>([
  {
    _id: "0",
    firstname: "Tim",
    lastname: "tom",
  },
]);

export function UserComponent({ children }: Props) {
  const [users, setUser] = useState<User[]>([]);

  return (
    <UserContext.Provider value={[users, setUser]}>
      {children}
    </UserContext.Provider>
  );
}

export default UserComponent;

I’m getting an error on the _id property in my array saying:
Type ‘{ _id: string; firstname: string; lastname: string; }’ is not assignable to type ‘User[]’.

What am i doing wrong?

Thanks for your help!

2

Answers


  1. Because you set the wrong default value to your context,
    replace your initial value of context with this.

    export const UserContext = createContext<ContextValue>([
        [
            {
                _id: '0',
                firstname: 'Tim',
                lastname: 'tom',
            },
        ],
        () => false,
    ]);
    
    

    () => false is a default function of your dispatch, you can change it for the better.

    Login or Signup to reply.
  2. 
    import React, {
      Dispatch,
      SetStateAction,
      createContext,
      useState,
    } from "react";
    
    type Props = {
      children: React.ReactNode;
    };
    
    type User = {
      _id: string;
      firstname: string;
      lastname: string;
    };
    
    type ContextValue = [User[], Dispatch<SetStateAction<User[]>>];
    
    // keep the default value of context as undefined, since u also have dispatch action u would need to pass both array of users and the dispatch action together
    export const UserContext = createContext<ContextValue | undefined>(undefined);
    
    export function UserProvider({ children }: Props) {
      const [users, setUser] = useState<User[]>([]);
    
      return (
        <UserContext.Provider value={[users, setUser]}>
          {children}
        </UserContext.Provider>
      );
    }
    
    // optionally u could also create a custom hook to access your provider
    
    export const useUserProvider = ()=>{
    const context = useContext(UserProvider);
      if(!context) throw new Error('useUserProvider must be used within the 
      scope of UserProvider');
      return context;
    }
    export default UserProvider;
    
    

    suggest to keep the createContext value as undefined since u would anyways provide the value for the context via the provider which makes the default value here unnecessary, since u have 2 required types in the array, the reason for getting the type error is that your context accepts an array of users as a first argument but on your example u have set it to be an object

    
    export const UserContext = createContext<ContextValue>([
      {
        _id: "0",
        firstname: "Tim",
        lastname: "tom",
      },
    ]);
    
    

    this should be changed to

    
    export const UserContext = createContext<ContextValue>([
      [{
        _id: "0",
        firstname: "Tim",
        lastname: "tom",
      }],
      ()=> {} // this will be required based on your type def
    ]);
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search