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);