javascript - React Typescript createContext 类型问题

标签 javascript reactjs typescript react-hooks

我正在尝试使用 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 初始化,上下文初始值将被替换,因此它们永远不会从组件中读取。

这样 todosaddNewTodo 将始终有一个值,TypeScript 不会提示。

关于javascript - React Typescript createContext 类型问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63237834/

相关文章:

javascript - 为什么我无法使用 Typescript/node.js 导入模块?

angular - Karma 断开连接,因为 10000 毫秒内没有消息

javascript - 是否有(静态)JavaScript 函数调用跟踪工具?

javascript - 向初次访问网站的访客显示有用提示的最佳方式 RoR/Jquery

node.js - reducer 和中间件有什么区别?

javascript - 我可以在 React 组件中使用相同的组件吗?

javascript - 有没有更好的方法来智能排序日期?

javascript - 如何仅更改 1 行而非全部的切换值

javascript - React Router(版本 6.0.2)使页面无响应 ReactJS

javascript - Angular 5 + Popper.JS