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