Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 反应&;TypeScript:避免上下文默认值_Reactjs_Typescript_React Hooks - Fatal编程技术网

Reactjs 反应&;TypeScript:避免上下文默认值

Reactjs 反应&;TypeScript:避免上下文默认值,reactjs,typescript,react-hooks,Reactjs,Typescript,React Hooks,为了更好地学习React、TypeScript和Context/Hooks,我正在制作一个简单的Todo应用程序。但是,创建上下文所需的代码感觉很麻烦 例如,如果我想更改Todo的内容,我必须在三个位置进行更改(ITodo接口、默认上下文值、默认状态值)。如果我想传递新的内容,我必须在三个位置(TodoContext、TodoContext的默认值和value=)进行传递。有没有更好的方法不必编写这么多代码 import React from 'react' export interface

为了更好地学习React、TypeScript和Context/Hooks,我正在制作一个简单的Todo应用程序。但是,创建上下文所需的代码感觉很麻烦

例如,如果我想更改Todo的内容,我必须在三个位置进行更改(ITodo接口、默认上下文值、默认状态值)。如果我想传递新的内容,我必须在三个位置(TodoContext、TodoContext的默认值和value=)进行传递。有没有更好的方法不必编写这么多代码

import React from 'react'

export interface ITodo {
    title: string,
    body?: string,
    id: number,
    completed: boolean
}

interface TodoContext {
    todos: ITodo[],
    setTodos: React.Dispatch<React.SetStateAction<ITodo[]>>
}

export const TodoContext = React.createContext<TodoContext>({
    todos: [{title: 'loading', body: 'loading', id: 0, completed: false}],
    setTodos: () => {}
})

export const TodoContextProvider: React.FC<{}> = (props) => {
    const [todos, setTodos] = React.useState<ITodo[]>([{title: 'loading', body: 'loading', id: 0, completed: false}])

    return (
        <TodoContext.Provider value={{todos, setTodos}}>
            {props.children}
        </TodoContext.Provider>
    )
}
从“React”导入React
导出接口ITodo{
标题:字符串,
主体?:字符串,
身份证号码:,
已完成:布尔值
}
与DoContext的接口{
待办事项:ITodo[],
setTodos:反应。调度
}
export const TodoContext=React.createContext({
todos:[{title:'loading',body:'loading',id:0,completed:false}],
setTodos:()=>{}
})
导出常量TodoContextProvider:React.FC=(道具)=>{
const[todos,setTodos]=React.useState([{title:'loading',body:'loading',id:0,completed:false}])
返回(
{props.children}
)
}

无法避免声明接口和运行时值,因为TS的类型在运行时消失,所以只剩下运行时值。不能从另一个生成一个

但是,如果您知道您只打算访问
TodoContextProvider
组件中的上下文,您可以通过欺骗一点并告诉TS您正在传递的内容没有问题来避免初始化
TodoContext

const TodoContext = React.createContext<TodoContext>({} as TodoContext)
const TodoContext=React.createContext({}作为TodoContext)
如果始终确保只访问
TodoContextProvider
中的上下文,其中
todos
setTodos
是使用
useState
创建的,则可以安全地跳过
createContext
中的初始化
TodoContext
,因为该初始值实际上永远不会被忽略已访问。

注意:

defaultValue参数仅在树中组件上方没有匹配的提供程序时使用

我更喜欢这样做的方式是通过实际指定默认值可以是
undefined

const TodoContext = React.createContext<ITodoContext | undefined>(undefined)
为什么我喜欢这种方法? 它会立即给我反馈为什么我的上下文值是未定义的


为了进一步的参考,请看一下这篇博文。过了一会儿,我想我已经找到了最好的方法

import React from 'react'

export interface ITodo {
    title: string,
    body?: string,
    id: number,
    completed: boolean
}

const useValue = () => {
    const [todos, setTodos] = React.useState<ITodo[]>([])

    return {
        todos,
        setTodos
    }
}

export const TodoContext = React.createContext({} as ReturnType<typeof useValue>)

export const TodoContextProvider: React.FC<{}> = (props) => {
    return (
        <TodoContext.Provider value={useValue()}>
            {props.children}
        </TodoContext.Provider>
    )
}
从“React”导入React
导出接口ITodo{
标题:字符串,
主体?:字符串,
身份证号码:,
已完成:布尔值
}
常量useValue=()=>{
const[todos,setTodos]=React.useState([])
返回{
待办事项,
塞托多斯
}
}
export const TodoContext=React.createContext({}作为ReturnType)
导出常量TodoContextProvider:React.FC=(道具)=>{
返回(
{props.children}
)
}

这样,在向上下文添加新内容时,只有一个变化点,而不是原来的三个变化点。享受吧

理想情况下,这看起来不错,但您可以使用redux并将其存储在redux存储中,并使用react redux connect使其在任何级别都可访问,这很好。是的,通常就是这样。谢谢
import React from 'react'

export interface ITodo {
    title: string,
    body?: string,
    id: number,
    completed: boolean
}

const useValue = () => {
    const [todos, setTodos] = React.useState<ITodo[]>([])

    return {
        todos,
        setTodos
    }
}

export const TodoContext = React.createContext({} as ReturnType<typeof useValue>)

export const TodoContextProvider: React.FC<{}> = (props) => {
    return (
        <TodoContext.Provider value={useValue()}>
            {props.children}
        </TodoContext.Provider>
    )
}