kus*_*lvm 31 typescript reactjs
我有一个按钮组件。我只是将onClick我定义的许多可选道具中的一个道具传递给它:
const Button = (props: ButtonProps) => {
const handleClick: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement> = e => {
props.onClick(e);
}
return (
<StyledButton onClick={handleClick}>
{props.children}
</StyledButton>
);
};
Run Code Online (Sandbox Code Playgroud)
然后我像这样使用它:
<Button onClick={(e) => {
console.log(e);
}}>Click me!</Button>
Run Code Online (Sandbox Code Playgroud)
现在如何根据所提到的错误,对象可能是未定义的?我清楚地将函数传递给它,并且根据类型定义也是如此。所以,我将一个对象传递给它。够简单!
...
onClick?: React.MouseEventHandler<HTMLElement>
...
Run Code Online (Sandbox Code Playgroud)
我最近在这个项目中添加了一些更严格的检查,相关的检查是:
"strictFunctionTypes": true,
"strictNullChecks": true
Run Code Online (Sandbox Code Playgroud)
strict:true 已经存在,此错误从未发生。
这里有什么问题?
更新 - 添加的类型
export interface IBaseButtonProps {
type?: ButtonType;
disabled?: boolean;
size?: ButtonSize;
block?: boolean;
loading?: boolean | { delay?: number };
icon?: string;
className?: string;
prefixCls?: string;
children?: React.ReactNode;
}
export type AnchorButtonProps = {
href: string,
target?: string,
onClick: React.MouseEventHandler<HTMLElement>
} & IBaseButtonProps & Omit<React.AnchorHTMLAttributes<any>, 'type' | 'onClick'>;
export type NativeButtonProps = {
onClick: React.MouseEventHandler<HTMLElement>,
htmlType?: ButtonHTMLType
} & IBaseButtonProps & Omit<React.ButtonHTMLAttributes<any>, 'type' | 'onClick'>;
export type ButtonProps = Partial<AnchorButtonProps & NativeButtonProps>
Run Code Online (Sandbox Code Playgroud)
笔记:
可能的解决方案是解构道具并添加默认道具。或者defaultProps从 React使用。但不确定我是否真的需要使用 Typescript。
Sha*_*tin 18
现在如何根据所提到的错误,对象可能是未定义的?[原文]
使用Partial<T>aroundexport type ButtonProps = Partial<AnchorButtonProps & NativeButtonProps>原因onClick是可选的。当我们使用Partial<T>,所有属性都接收?并因此成为可选的,这意味着它们都可以是未定义的。
有两种修复方法:一种是ButtonProps与onClick可选的保持相同,并onClick在调用之前检查它的定义(修复 1);另一种是改变ButtonProps使onClick必需的(修复 2 和 3)。
onClick仍然是可选的使用ButtonProps您已有的 ,然后onClick在调用之前检查已定义的 。这就是antd在您在注释中链接的代码中所做的。
const Button = (props: ButtonProps) => {
const handleClick: React.MouseEventHandler<
HTMLButtonElement | HTMLAnchorElement
> = e => {
if (props.onClick) props.onClick(e); // works
};
};
Run Code Online (Sandbox Code Playgroud)
onClick成为必需ButtonProps通过不将 应用于Partial来更改NativeButtonProps:
type ButtonProps1 = Partial<AnchorButtonProps> & NativeButtonProps;
const Button1 = (props: ButtonProps1) => {
const handleClick: React.MouseEventHandler<
HTMLButtonElement | HTMLAnchorElement
> = e => {
props.onClick(e); // works
};
};
Run Code Online (Sandbox Code Playgroud)
onClick变得需要定义一个RequireKeys类型,它允许您指定非可选的键。
const Button = (props: ButtonProps) => {
const handleClick: React.MouseEventHandler<
HTMLButtonElement | HTMLAnchorElement
> = e => {
if (props.onClick) props.onClick(e); // works
};
};
Run Code Online (Sandbox Code Playgroud)
映射类型的答案:删除可选修饰符包含有关我如何定义RequireKeys<T>.
kis*_*ore 10
只是一个明确的答案
if (props.onClick) props.onClick(e);
如果您正在定义一个函数 props 并希望它是可选的,请将其定义为,
export type ButtonProps = {
function?: () => void;
};
Run Code Online (Sandbox Code Playgroud)
说明: 如果您想使用函数作为 props,则可能在某些情况下您希望传递该函数(作为 props),而在其他情况下您可能不想传递它。
例如,
通用代码在哪里调用
<Home/>组件,例如index.ts/index.js
function myfunction(){
//do something
alert("hello")
}
return (
<>
<Home myfunction={myfunction}/> //passing prop
<Home/> // not passing
</>
)
Run Code Online (Sandbox Code Playgroud)
在 JS 中,home.js
export default function Home({myfunction}) {
const const1 = "Hello World"
return (
//do something
myfunction(); //IMPORTANT line
)
}
Run Code Online (Sandbox Code Playgroud)
现在,它几乎相当于 TS,home.ts
在 TS 中,我们定义了一切的类型。因此,在这种情况下,我们还必须定义myfunction我们传递的该函数的类型。
因此,对于这个函数,我们意识到,
()(空括号)就足够了,如果有任何参数,我们还需要为它们定义类型。voidexport type HomeProps = {
myfunction?: () => void;
};
export default function Home({ myfunction }: HomeProps) {
const const1 = "Hello World"
return (
//do something
if (myfunction) myfunction(); //IMPORTANT line
)
}
Run Code Online (Sandbox Code Playgroud)
提示:以上答案
逻辑运算符 AND (&&) 返回它找到的第一个假操作数的值,或者如果所有值均为真则返回最后一个操作数的值 ( Source )。因此,我们可以简单地写:
(props.onClick && props.onClick(e));
Run Code Online (Sandbox Code Playgroud)
我正在创建自己的自定义 MUI 按钮,这就是我的做法。
interface ButtonTypes {
handleClick?: React.MouseEventHandler<HTMLButtonElement> | undefined
}
Run Code Online (Sandbox Code Playgroud)
在按钮组件上
<LoadingButton
onClick={(e) =>handleClick && handleClick(e)}
>
{"Send"}
</LoadingButton>
Run Code Online (Sandbox Code Playgroud)
如果您使用的是 VScode,请将鼠标悬停在该OnClick属性上,您应该会看到预期的类型。
使用 Typescript 3.7+,您还可以使用可选链来调用可选的 prop 方法:
const Button = (props: ButtonProps) => {
const handleClick: React.MouseEventHandler<
HTMLButtonElement | HTMLAnchorElement
> = e => {
props.onClick?.(e); // works
};
};
Run Code Online (Sandbox Code Playgroud)
您可以阅读有关使用可选链接的更多信息 - https://www.stefanjudis.com/today-i-learned/optional-chaining-helps-to-avoid-undefined-is-not-a-function-exceptions/
| 归档时间: |
|
| 查看次数: |
58325 次 |
| 最近记录: |