J'ai une composante de bouton. Je le transmette simplement juste un onClick
Procédez à de nombreux accessoires facultatifs que j'ai définis.
const Button = (props: ButtonProps) => {
const handleClick: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement> = e => {
props.onClick(e);
}
return (
<StyledButton onClick={handleClick}>
{props.children}
</StyledButton>
);
};
Alors j'utilise comme ça
<Button onClick={(e) => {
console.log(e);
}}>Click me!</Button>
Maintenant, comment peut-on mentionner l'erro en question, objet être éventuellement indéfini? Je crois clairement la fonction et cela aussi selon la définition de type. Donc, je passe un objet à cela. Assez simple!
...
onClick?: React.MouseEventHandler<HTMLElement>
...
J'ai ajouté quelques contrôles plus stricts dans ce projet récemment et pertinents sont
"strictFunctionTypes": true,
"strictNullChecks": true
strict:true
ÊTRE DÉJÀ présent, cette erreur n'a jamais eu lieu.
Quel est le problème ici?
Mise à jour - Types ajoutés
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>
Remarques -
La solution possible consiste à déstructurer les accessoires et à ajouter le projet par défaut. Ou utiliser despitres de défaut de réacteur. Mais pas sûr si je devrais exiger cela vraiment avec des documents.
juste une réponse transparente
if (props.onClick) props.onClick(e);
si vous définissez des accessoires de fonction et que vous voulez qu'il soit facultatif, définissez-le comme étant,
export type ButtonProps = {
function?: () => void;
};
Explication : Si vous souhaitez utiliser une fonction comme des accessoires, il peut y avoir des instances lorsque vous souhaitez transmettre cette fonction (en tant que accessoires) et il peut y avoir d'autres instances où vous ne voulez pas le transmettre.
par exemple,
Code commun où appeler le
<Home/>
composant, disons index.ts/index.js
function myfunction(){
//do something
alert("hello")
}
return (
<>
<Home myfunction={myfunction}/> //passing prop
<Home/> // not passing
</>
)
En JS, home.js
export default function Home({myfunction}) {
const const1 = "Hello World"
return (
//do something
myfunction(); //IMPORTANT line
)
}
Maintenant, c'est presque équivalent dans TS, Home.TS
Dans TS, nous définissons des types de tout. Donc, dans ce cas, nous devons définir le type de cette fonction myfunction
aussi, que nous passons.
Donc, pour cette fonction, nous réalisons que,
()
(parenthèse vide) suffit, si des paramètres sont là, nous devons également définir des types pour eux également.void
export type HomeProps = {
myfunction?: () => void;
};
export default function Home({ myfunction }: HomeProps) {
const const1 = "Hello World"
return (
//do something
if (myfunction) myfunction(); //IMPORTANT line
)
}
Astuce: ci-dessus répondre
?.call(this: unknown, ...args: any[])
ou ?.apply(this: unknown, args: any[])
méthodesDonc, imaginons que nous avons les prochaines déclarations
type callback = ((x: number, y: number) => number) | null;
let a: callback;
let b: callback;
a = (x, y) => x + y; // it works with arrow functions
b = function (x, y) { // and normal functions
return x + y;
};
function x(cb1: callback, cb2: callback) {
console.log(cb1?.call(0, 5, 6)); // in this case you
console.log(cb2?.call(0, 5, 6)); // cant invoke cb1() or cb2()
console.log(cb1?.apply(0, [5, 6])); // but you can use call or apply
console.log(cb2?.apply(0, [5, 6])); // where first parameter can be any value
}
x(a, b); // 11 11 11 11
class C {
public f?: callback;
public setF() {
this.f = (x, y) => {
return x + y;
};
}
}
const c = new C(); // same with objects
c.setF();
console.log(c?.f?.call(c, 2, 3)); // 5