我正在尝试使用 React Context Hook 和 typescript 传递 todos
(初始状态)和 addNewTodo
(方法)。我尝试了多种解决方案但没有成功,仍然出现错误。
Partial
泛型在上下文组件上没有问题,但它给了我错误 Cannot invoke an object which possibly 'undefined'
while calling addNewTodo
在 todo 表单组件中。
同样,undefined 和 empty objects {} 也会给出不同的错误。无法弄清楚如何解决它。如果我传递 any
,则 IntelliSense 将不起作用。
这是我的代码
待办事项
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>
)
}
待办事项表单
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>
)
}
我们将不胜感激。
最佳答案
为了防止 TypeScript 告知对象的属性未定义,我们需要定义它们(使用 Partial 将每个属性设置为可能未定义,我们希望避免这种情况)。
这意味着我们需要在定义上下文时为每个属性传递一些值:
export const TaskListContext = createContext<TaskContextProps>({
todos: [],
addNewTodo: () => {}
});
一旦 Provider 初始化,上下文初始值将被替换,因此它们永远不会从组件中读取。
这样 todos
和 addNewTodo
将始终有一个值,TypeScript 不会提示。
关于javascript - React Typescript createContext 类型问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63237834/