I am trying to pass todos (initial state) and addNewTodo (methods) using React Context hook and typescript. I have tried multiple solutions but no success, still getting errors.
Partial generics doesn't give issue on context component, but it gives me the error Cannot invoke an object which is possibly 'undefined' while calling addNewTodo in todo form component.
Similarly, undefined and empty objects {} also give different errors. Can't figure out how to fix it. If I pass any then IntelliSense won't work.
Here is my code
TodoContext
import React, { useState, createContext, FC, useContext } from "react"
type Props = {
children: React.ReactNode,
}
interface TaskContextProps {
todos: Todo[],
addNewTodo: addNewTodo
}
const initialTodos: Array<Todo> = [
{ id: 1, text: 'buy some milk', completed: false },
{ id: 2, text: 'go to gym', completed: false }
]
export const TaskListContext = createContext<Partial<TaskContextProps>>({})
// export const TaskListContext = createContext<TaskContextProps>({})
// export const TaskListContext = createContext<TaskContextProps | undefined>(undefined)
const TaskListContextProvider: FC<Props> = ({ children }) => {
const [todos, setTodos] = useState(initialTodos)
const addNewTodo: addNewTodo = (newTodo) => {
setTodos([newTodo, ...todos])
}
return (
<TaskListContext.Provider value={{ todos, addNewTodo }}>
{children}
</TaskListContext.Provider>
)
}
Todo Form
import React, { useState, ChangeEvent, FormEvent, useContext } from 'react';
// import { useTaskList, TaskListContext } from '../context/TaskListContext';
import { TaskListContext } from '../context/TaskListContext';
const TodoForm = () => {
const [newTodo, setNewTodo] = useState('')
// const { addNewTodo } = useTaskList()
const { addNewTodo } = useContext(TaskListContext)
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
setNewTodo(e.target.value)
}
const handleSubmit = (e: FormEvent<HTMLButtonElement>) => {
e.preventDefault()
const addTodo = { id: Math.random(), text: newTodo, completed: false }
if (newTodo.trim()) {
addNewTodo(addTodo)
}
else {
alert('Todo can\'t be empty')
}
setNewTodo('')
}
return (
<form>
<input placeholder='your todo...' value={newTodo} onChange={handleChange} />
<button onClick={handleSubmit}>Submit</button>
</form>
)
}
Your help will be appreciated.