Javascript Typescript抱怨react组件可选属性可能未定义
我有一个简单的反应组件,如下所示:Javascript Typescript抱怨react组件可选属性可能未定义,javascript,reactjs,typescript,frontend,Javascript,Reactjs,Typescript,Frontend,我有一个简单的反应组件,如下所示: interface ComponentProps { onClick?: () => void; } const Component = (props: ComponentProps) => { if (!props.onClick) { return <></>; } return ( // Typescript complains: Cannot inv
interface ComponentProps {
onClick?: () => void;
}
const Component = (props: ComponentProps) => {
if (!props.onClick) {
return <></>;
}
return (
// Typescript complains: Cannot invoke an object which is possibly 'undefined'.ts(2722)
<button onClick={() => props.onClick()}>
test
</button>
);
};
接口组件支柱{
onClick?:()=>void;
}
常量组件=(props:ComponentProps)=>{
如果(!props.onClick){
返回;
}
返回(
//Typescript抱怨:无法调用可能“未定义”的对象。ts(2722)
props.onClick()}>
测试
);
};
Typescript抱怨props.onClick可能未定义,即使在检查之后
有人能帮我理解为什么props.onClick仍然可以不被定义吗?使用props.onClick()
而不是props.onClick()
这告诉typescript仅在定义onClick()时调用它
问题在于,您的
道具
对象是可变的,TypeScript假定它可以在之间进行修改!props.onClick
检查并执行回调
要解决此问题,可以对props
对象进行分解,并将onClick
属性用作范围变量:
const Component = ({onClick}: ComponentProps) => {
if (!onClick) {
return <></>;
}
return (
<button onClick={() => onClick()}>
test
</button>
);
};
const Component=({onClick}:ComponentProps)=>{
如果(!onClick){
返回;
}
返回(
onClick()}>
测试
);
};
你为什么不试试
interface ComponentProps {
onClick?: () => void;
}
const Component = ({ onClick = () => {}}: ComponentProps) => {
return (
<button onClick={() => props.onClick()}>
test
</button>
);
};
接口组件支柱{
onClick?:()=>void;
}
const Component=({onClick=()=>{}}:ComponentProps)=>{
返回(
props.onClick()}>
测试
);
};
这是因为您在组件属性
接口定义中使用了?
我认为有两种方法可以解决这个问题:
第一个是将可选属性定义更改为强制删除?
可选属性运算符,因此不需要验证onClick
函数是否传递给组件
interface ComponentProps {
onClick?: () => void;
}
const Component = ({onClick}) => (
<button onClick={onClick}>
test
</button>
)
interface ComponentProps {
onClick: () => void;
}
const Component = ({onClick}: ComponentProps) => (
<button {...(onClick ? {onClick} : {})}>test</button>
)
奖金。 您可以同时使用扩展语法和三元运算符来验证传递给React组件的可选属性
interface ComponentProps {
onClick?: () => void;
}
const Component = ({onClick}) => (
<button onClick={onClick}>
test
</button>
)
interface ComponentProps {
onClick: () => void;
}
const Component = ({onClick}: ComponentProps) => (
<button {...(onClick ? {onClick} : {})}>test</button>
)
接口组件支柱{
onClick:()=>void;
}
常量组件=({onClick}:ComponentProps)=>(
测试
)
您将onClick()
标记为可选,这意味着它可以不定义。尝试从界面中删除onClick()
之后的问号。我知道这是可选的,删除?让抱怨消失。但我的问题是,为什么在检查(!props.onClick)是否返回之后;props.onClick仍然可能是未定义的,这是因为您正在回调中使用它。这是因为从理论上讲,在回调调用之前,其他一些代码可以更改道具,并可能将未定义的分配给道具。onClick
。类似的问题如果你使用destructureconst Component=({onClick}:ComponentProps)=>{…}
语法,它应该修复它,因为当它被这样解构时,你不能重新分配onClick
。如果props发生了变化,比如说props.onClick变为undefined,然后它会触发重新渲染,对吗?如果是这样,按钮将不再渲染。我的意思是,如果未定义props.onClick,则没有按钮,如果定义了props.onClick,则有按钮。我理解正确吗?@Ethan否。如果道具
对象发生变异,React将不会意识到它,也不会重新渲染组件。在React世界中,道具
对象永远不会变异。渲染组件时,它将接收一个新的props
对象。问题是TypeScript不知道React在内部是如何工作的,即使从来都不是这样,它也假设props
对象可以变异。