Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.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 无法调用可能为';未定义';。ts(2722)_Reactjs_Typescript - Fatal编程技术网

Reactjs 无法调用可能为';未定义';。ts(2722)

Reactjs 无法调用可能为';未定义';。ts(2722),reactjs,typescript,Reactjs,Typescript,我有一个按钮组件。我只需将我定义的许多可选道具中的一个onClickprop传递给它: const按钮=(道具:按钮操作)=>{ 常量handleClick:React.MouseEventHandler=e=>{ 道具。onClick(e); } 返回( {props.children} ); }; 然后我就这样使用它: { 控制台日志(e); }}>点击我! 现在,根据问题中提到的错误,对象如何可能是未定义的?很明显,我正在将函数传递给它,而且根据类型定义也是如此。所以,我向它传递一个对

我有一个按钮组件。我只需将我定义的许多可选道具中的一个
onClick
prop传递给它:

const按钮=(道具:按钮操作)=>{
常量handleClick:React.MouseEventHandler=e=>{
道具。onClick(e);
}
返回(
{props.children}
);
};
然后我就这样使用它:

{
控制台日志(e);
}}>点击我!
现在,根据问题中提到的错误,对象如何可能是未定义的?很明显,我正在将函数传递给它,而且根据类型定义也是如此。所以,我向它传递一个对象。很简单

。。。
onClick?:React.MouseEventHandler
...
我最近在该项目中增加了一些更严格的检查,相关检查包括:

“strictFunctionTypes”:true,
“strictNullChecks”:true
strict:true
已存在,此错误从未发生

这里有什么问题

更新-添加的类型

导出接口IBaseButtonProps{
类型?:按钮类型;
禁用?:布尔值;
大小?:按钮化;
块?:布尔;
加载?:布尔|{延迟?:数字};
图标?:字符串;
类名?:字符串;
prefixCls?:字符串;
子节点?:React.ReactNode;
}
导出类型AnchorButtonProps={
href:string,
目标?:字符串,
onClick:React.MouseEventHandler
}&IBaseButtonProps&省略;
导出类型NativeButtonProps={
onClick:React.MouseEventHandler,
htmlType?:按钮htmlType
}&IBaseButtonProps&省略;
导出类型按钮操作=部分
注:

可能的解决方案是分解道具并添加默认道具。或者使用React中的
defaultProps
。但不确定我是否真的需要Typescript

现在,根据问题中提到的错误,对象如何可能是未定义的?[原文如此]

在注释中链接的代码中使用
Partial
round
export-type buttonrops=Partial

const Button = (props: ButtonProps) => {
  const handleClick: React.MouseEventHandler<
    HTMLButtonElement | HTMLAnchorElement
  > = e => {
    if (props.onClick) props.onClick(e); // works
  };
};
修复3:
onClick
也成为必需的 定义一个
RequireKeys
类型,用于指定非可选的键

type RequireKeys=T&
{[P in keyof T]-?:P扩展TNames?T[P]:never};
键入ButtonProps2=所需键;
const Button2=(道具:ButtonProps2)=>{
const handleClick:React.MouseEventHandler<
HTMLButtoneElement | HTMLLanchoreElement
>=e=>{
props.onClick(e);//有效
};
};

关于我如何定义
RequireKeys

的更多信息,答案非常明确

if(props.onClick)props.onClick(e)

如果您要定义一个函数props并希望它是可选的,请将其定义为

export type ButtonProps = {
  function?: () => void;
};
说明: 如果希望将函数用作道具,则可能存在希望传递该函数(作为道具)的实例,也可能存在不希望传递该函数的其他实例

比如说,

调用组件的通用代码,例如index.ts/index.js

现在,它几乎等同于TS,home.TS

在TS中,我们定义了所有事物的类型。所以,在这种情况下,我们还必须定义我们要传递的这个函数的类型
myfunction

因此,对于这个函数,我们意识到

  • 它不接收任何参数,所以
    ()
    (空括号)就足够了,如果有任何参数,我们也需要为它们定义类型
  • 不返回任何内容,因此返回类型
    void

提示:以上答案

最好的变体是使用
?。调用(this:unknown,…args:any[])
?。应用(this:unknown,args:any[])
方法 那么,让我们设想下一个声明

type callback=((x:number,y:number)=>number)|空;
让a:回调;
让b:回调;
a=(x,y)=>x+y;//它与箭头函数一起工作
b=函数(x,y){//和正规函数
返回x+y;
};
函数x(cb1:回调,cb2:回调){
console.log(cb1?.call(0,5,6));//在本例中
console.log(cb2?.call(0,5,6));//无法调用cb1()或cb2()
console.log(cb1?.apply(0[5,6]);//但是您可以使用call或apply
console.log(cb2?.apply(0[5,6]);//其中第一个参数可以是任何值
}
x(a,b);//11 11 11 11
C类{
公共f?:回调;
公共setF(){
这个.f=(x,y)=>{
返回x+y;
};
}
}
常数c=新的c();//对象也是如此
c、 setF();
console.log(c?.f?.call(c,2,3));//5.

对于Typescript 3.7+,您还可以使用可选链接来调用可选的prop方法:

const Button = (props: ButtonProps) => {
  const handleClick: React.MouseEventHandler<
    HTMLButtonElement | HTMLAnchorElement
  > = e => {
    props.onClick?.(e); // works
  };
};
const按钮=(道具:按钮操作)=>{
const handleClick:React.MouseEventHandler<
HTMLButtoneElement | HTMLLanchoreElement
>=e=>{
props.onClick?(e);//有效
};
};

您可以阅读更多有关使用可选链接的信息-

供下一位读者阅读。另一种选择是使用类型转换。 比如:

根据我的经验,我使用了一个返回部分类型对象的上下文,我需要进行类型转换以克服未定义的错误。比如:

const {setSomething} = useContext(SomePartialContext) as MyContextType

onClick?:反应。MouseEventHandler
表示可以取消定义
onClick
。因为它是可选的,所以请删除
以使
onClick
成为必需的。如果它是可选的,它可以定义为未定义的,因为我不能从
onClick
中删除
,添加defaultProps与typescript一起是一个好主意吗?看来我现在得做了。但是我在很多文章中读到了使用TS ONLY处理
defaultProps
,即使删除了可选标记,仍然是相同的家伙,这对Typescript来说是非常新的。因此,从这里的生产级代码一步一步地理解——它们使用相同的方法。这会是版本问题吗?如果您看到他们没有为
o指定任何
defaultProps
export default function Home({myfunction}) {
  const const1 = "Hello World"
  return (
    //do something
    myfunction();      //IMPORTANT line
  )
}
export type HomeProps = {
  myfunction?: () => void;
};

export default function Home({ myfunction }: HomeProps) {
  const const1 = "Hello World"
  return (
    //do something
    if (myfunction) myfunction();      //IMPORTANT line
  )
}
 (props.onClick && props.onClick(e));
const Button = (props: ButtonProps) => {
  const handleClick: React.MouseEventHandler<
    HTMLButtonElement | HTMLAnchorElement
  > = e => {
    props.onClick?.(e); // works
  };
};
props = props as NativeProps
const {setSomething} = useContext(SomePartialContext) as MyContextType