web-dev-qa-db-fra.com

Comment attribuer le typage correct à React.cloneElement lors de l'attribution de propriétés aux enfants?

J'utilise React et TypeScript. J'ai un composant react qui agit comme un wrapper, et je souhaite copier ses propriétés dans ses enfants. Je suis le guide de React pour utiliser l'élément clone: ​​- https://facebook.github.io/react/blog/2015/03/03/react-v0.13-rc2.html#react.cloneelement . Mais lors de l'utilisation avec React.cloneElement J'obtiens l'erreur suivante de TypeScript:

Argument of type 'ReactChild' is not assignable to parameter of type 'ReactElement<any>'.at line 27 col 39
  Type 'string' is not assignable to type 'ReactElement<any>'.

Comment puis-je attribuer les bons caractères à react.cloneElement?

Voici un exemple qui reproduit l'erreur ci-dessus:

import * as React from 'react';

interface AnimationProperties {
    width: number;
    height: number;
}

/**
 * the svg html element which serves as a wrapper for the entire animation
 */
export class Animation extends React.Component<AnimationProperties, undefined>{

    /**
     * render all children with properties from parent
     *
     * @return {React.ReactNode} react children
     */
    renderChildren(): React.ReactNode {
        return React.Children.map(this.props.children, (child) => {
            return React.cloneElement(child, { // <-- line that is causing error
                width: this.props.width,
                height: this.props.height
            });
        });
    }

    /**
     * render method for react component
     */
    render() {
        return React.createElement('svg', {
            width: this.props.width,
            height: this.props.height
        }, this.renderChildren());
    }
}
37
David C

Le problème est que la définition de ReactChild est la suivante:

type ReactText = string | number;
type ReactChild = ReactElement<any> | ReactText;

Si vous êtes sûr que child est toujours un ReactElement, convertissez-le:

return React.cloneElement(child as React.ReactElement<any>, {
    width: this.props.width,
    height: this.props.height
});

Sinon, utilisez le garde de type isValidElement :

if (React.isValidElement(child)) {
    return React.cloneElement(child, {
        width: this.props.width,
        height: this.props.height
    });
}

(Je ne l'ai pas utilisé auparavant, mais selon le fichier de définition, il est là)

62
Nitzan Tomer