Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.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
Javascript Typescript抱怨react组件可选属性可能未定义_Javascript_Reactjs_Typescript_Frontend - Fatal编程技术网

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
。类似的问题如果你使用destructure
const Component=({onClick}:ComponentProps)=>{…}
语法,它应该修复它,因为当它被这样解构时,你不能重新分配
onClick
。如果props发生了变化,比如说props.onClick变为undefined,然后它会触发重新渲染,对吗?如果是这样,按钮将不再渲染。我的意思是,如果未定义props.onClick,则没有按钮,如果定义了props.onClick,则有按钮。我理解正确吗?@Ethan否。如果
道具
对象发生变异,React将不会意识到它,也不会重新渲染组件。在React世界中,
道具
对象永远不会变异。渲染组件时,它将接收一个新的
props
对象。问题是TypeScript不知道React在内部是如何工作的,即使从来都不是这样,它也假设
props
对象可以变异。