Home > Software design >  React typescript error in todo app with context
React typescript error in todo app with context

Time:02-19

I'm trying to create a simple react todo app using context and with typescript

I have a stackblitz here

so the app is working but I have typescript errors that I'm struggling to fix.

so I have a Prodivder like

import React from 'react';
import {
  createContext,
  useContext,
  useState,
  ReactChildren,
  ReactChild,
} from 'react';

interface AuxProps {
  children: ReactChild | ReactChildren;
}

const defaultContext = ['todo', 'another todo'];

const TodoContext = createContext<string[]>(defaultContext);

const TodoProvider = ({ children }: AuxProps) => {
  const [todoList, setTodoList] = useState(defaultContext);

  const contextValue = {
    todoList,
  };

  return (
    <TodoContext.Provider value={contextValue}>{children}</TodoContext.Provider>
  );
};

export const useTodoContext = () => useContext(TodoContext);

export default TodoProvider;

here the value has a typescript error saying

Type '{ todoList: string[]; }' is missing the following properties from type 'string[]': length, pop, push, concat, and 25 more.    

here Ive created a useTodoContext hook and I'm using on it the TodoList component

import React from 'react';
import { useTodoContext } from './TodoProvider';

const TodoList = () => {
  const { todoList } = useTodoContext();

  return (
    <ul>
      {todoList.map((todo: any, index: number) => (
        <li key={index}>{todo}</li>
      ))}
    </ul>
  );
};

export default TodoList;

here the useTodoContext todoList has a typescript error saying

Property 'todoList' does not exist on type 'string[]'.  

I think both these errors rw from the actual todo not having a type but I'm struggling to get that to work

CodePudding user response:

You should pass todoList to provider value :

 return (
    <TodoContext.Provider value={todoList}>{children}</TodoContext.Provider>
  );

Then get it like this :

const todoList = useTodoContext();

I fixed it here

CodePudding user response:

You have a mismatch between what type you say the context will contain, and how you try to actually use it. You define the context so it contains an array of strings:

const defaultContext = ['todo', 'another todo'];

const TodoContext = createContext<string[]>(defaultContext);

However, where you actually use the context, you're treating it as though it will be an object with a .todoList property that is an array. If the definition of a string[] is correct, then change how you provide the context to this:

const [todoList, setTodoList] = useState(defaultContext);

return <TodoContext.Provider value={todoList}>{children}</TodoContext.Provider>

And change how you consume it like this:

const TodoList = () => {
  const todoList = useTodoContext();

Alternatively, if the definition is wrong and should be an object instead, change it to this:

const defaultContext = {
  todoList: ['todo', 'another todo']
};

const TodoContext = createContext<{ todoList: string[] }>(defaultContext);
  • Related