簡體   English   中英

反應 Typescript createContext 類型問題

[英]React Typescript createContext types issue

我正在嘗試使用 React Context 掛鈎和 typescript 傳遞todos (初始狀態)和addNewTodo (方法)。我嘗試了多種解決方案但沒有成功,仍然出現錯誤。

Partial generics 在上下文組件上沒有給出問題,但它給了我錯誤Cannot invoke an object which is possibly 'undefined' calling addNewTodo in todo form component. 同樣,undefined 和 empty objects {} 也會給出不同的錯誤。 無法弄清楚如何解決它。 如果我通過any測試,則 IntelliSense 將無法工作。

這是我的代碼

Todo上下文

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 告訴我們 object 的屬性未定義,我們需要定義它們(使用 Partial 將每個屬性設置為可能未定義,我們希望避免這種情況)。

這意味着我們需要在定義上下文時為每個屬性傳遞一些值:

export const TaskListContext = createContext<TaskContextProps>({
    todos: [],
    addNewTodo: () => {}
});

Provider 初始化后,上下文初始值將被替換,因此它們永遠不會從組件中讀取。

這樣todosaddNewTodo將始終有一個值,並且 TypeScript 不會抱怨。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM