My code
interface ButtonProps {
onClick?: () => void
}
const Button: FC<ButtonProps> = ({ onClick }) => {
const wrapClick = () => {
onClick() // TS2722: Cannot invoke an object which is possibly 'undefined'.
}
return <button onClick={wrapClick}>button</button>
}
Button.defaultProps = {
onClick: () => {},
}
In this case, everything works
const Button: FC<ButtonProps> = ({ onClick }) => {
const wrapClick = () => {
onClick && onClick()
}
return <button onClick={wrapClick}>button</button>
}
and in this
const Button: FC<ButtonProps> = ({ onClick = () => {} }) => {
const wrapClick = () => {
onClick()
}
return <button onClick={wrapClick}>button</button>
}
Is there a way to use default props to solve this problem ? Since I have large components with a lot of properties.
CodePudding user response:
The onClick property in the props object is marked as optional by using a question mark, so we can't directly invoke the function.
To solve the error, use the optional chaining (?.) operator when calling the function.
import { FC } from "react";
interface ButtonProps {
onClick?: () => void;
}
const Button: FC<ButtonProps> = ({ onClick }) => {
const wrapClick = () => {
onClick?.();
};
return <button onClick={wrapClick}>button</button>;
};
Button.defaultProps = {
onClick: () => {}
};
export default Button;
CodePudding user response:
Use the Non-null
assertion operator (postfix !
) to let TypeScript know your default onClick(): void
is not null
/undefined
(which it thinks it is because of IButtonProps.onClick: () => void | undefined
, which is used by Button
(FC<IButtonProps>
, FC<T>.defaultProps
is of type T & { children?: Node }
if I remember correctly)).
interface IButtonProps {
onClick?: () => void; // No event args?
}
const Button: FC<IButtonProps> = (props) => {
const {
onClick = Button.defaultProps.onClick!,
} = props;
const wrapClick = (/* No event args? */) => {
onClick();
};
return <button onClick={wrapClick}>button</button>;
};
Button.defaultProps = {
onClick: () => {},
};