Typescript抱怨react组件的可选属性可能未定义

时间:2020-10-30 08:07:13

标签: javascript reactjs typescript frontend

我有一个简单的React组件,像这样:

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>
    );
};

打字稿抱怨props.onClick可能是不确定的,即使经过检查。

有人可以帮助我理解为什么props.onClick可能 仍然 未定义的原因吗?

4 个答案:

答案 0 :(得分:1)

这是因为您在 ? 接口定义中使用了 optional property operator ComponentProps

我看到了两种解决此问题的方法:

第一个是将可选属性定义更改为强制删除 ? 可选属性运算符,因此您无需验证 onClick 函数是否传递给组件。

interface ComponentProps {
   onClick: () => void;
}
const Component = ({onClick}) => (
   <button onClick={onClick}>
       test
   </button> 
)

我 第二个是创建处理函数以验证可选的 onClick 函数。

inteface ComponentProps {
    onClick?: () => void;
}
const Component = ({onClick}: ComponentProps) => (
   <button onClick={() => {
       if(onClick) onClick();
   }}>  
       test
   </button>
)

奖金。 您可以结合使用扩展语法和三元运算符来验证传递给 React 组件的可选属性。

interface ComponentProps {
   onClick?: () => void;
}
const Component = ({onClick}: ComponentProps) => (
   <button {...(onClick ? {onClick} : {})}>test</button>
)

答案 1 :(得分:0)

问题是您的props对象是可变的,并且TypeScript假定可以在您的!props.onClick检查和执行回调之间对其进行修改。

要解决您的问题,您可以分解props对象,并将onClick属性用作范围变量:

const Component = ({onClick}: ComponentProps) => {
    if (!onClick) {
        return <></>;
    }

    return (
        <button onClick={() => onClick()}>  
            test
        </button>
    );
};

答案 2 :(得分:0)

你为什么不尝试

interface ComponentProps {
    onClick?: () => void;
}

const Component = ({ onClick = () => {}}: ComponentProps) => {


    return (
      
        <button onClick={() => props.onClick()}>  
            test
        </button>
    );
};

答案 3 :(得分:-1)

使用props.onClick?.()代替props.onClick()

这告诉打字稿仅在定义时才调用onClick()。

Learn more about optional chaining here