web-dev-qa-db-fra.com

Problème de compréhension de l'opérateur d'étalement JSX

Étant donné cet exemple de code provenant des documents React:

var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;

J'ai fait quelques recherches sur ce que ...props évalue réellement, c'est-à-dire:

React.__spread({}, props)

Qui, à son tour, évalue à {foo: x, bar: y}.

Mais ce que je me demande, c'est pourquoi je ne peux pas simplement faire ceci:

var component = <Component props />;

Je ne vois pas quel est l'intérêt de l'opérateur de spread.

25
ffxsam

Cela aide à rendre votre code plus succinct - puisque props est un objet, l'opérateur de propagation prend les propriétés de l'objet que vous passez et les applique au composant. Ainsi, le composant aura les propriétés un foo avec une valeur de x et un bar avec une valeur de y.

Ce serait la même chose que:

var component = <Component foo={props.foo} bar={props.bar} />;

juste plus court

24
pherris

L'une des meilleures vues d'ensemble de la façon dont fonctionne la syntaxe de propagation d'objet au repos avec react est publiée sur reactpatterns.com :

Attributs de propagation JSX

Spread Attributes est une fonctionnalité JSX. C'est du sucre syntaxique pour passer toutes les propriétés d'un objet en tant qu'attributs JSX.

Ces deux exemples sont équivalents.

// props written as attributes
<main className="main" role="main">{children}</main>

// props "spread" from object
<main {...{className: "main", role: "main", children}} />

Utilisez-le pour transférer props vers les composants sous-jacents.

const FancyDiv = props =>
  <div className="fancy" {...props} />

Maintenant, je peux m'attendre à ce que FancyDiv ajoute les attributs qui le concernent ainsi que ceux qui ne le sont pas.

<FancyDiv data-id="my-fancy-div">So Fancy</FancyDiv>

// output: <div className="fancy" data-id="my-fancy-div">So Fancy</div>

Gardez à l'esprit que l'ordre est important. Si props.className Est défini, il encombrera le className défini par FancyDiv

<FancyDiv className="my-fancy-div" />

// output: <div className="my-fancy-div"></div>

Nous pouvons faire en sorte que FancyDivs className "gagne" toujours en le plaçant après les accessoires de propagation ({...props}).

// my `className` clobbers your `className`
const FancyDiv = props =>
  <div {...props} className="fancy" />

Vous devez gérer ces types d'accessoires avec élégance. Dans ce cas, je vais fusionner le props.className De l'auteur avec le className nécessaire pour styliser mon composant.

const FancyDiv = ({ className, ...props }) =>
  <div
    className={["fancy", className].join(' ')}
    {...props}
  />

- cité de reactpatterns.com par @ chantastic


Un autre bon aperçu a été publié sur le blog de babeljs React on ES6 + par Steven Luscher:

Attributs de déstructuration et de propagation

Souvent, lors de la composition de composants, nous souhaitons peut-être transmettre la plupart des accessoires d'un composant parent à un composant enfant, mais pas tous. En combinant la déstructuration ES6 + avec les attributs de propagation JSX, cela devient possible sans cérémonie:

class AutoloadingPostsGrid extends React.Component {
  render() {
    const {
      className,
      ...others  // contains all properties of this.props except for className
    } = this.props;
    return (
      <div className={className}>
        <PostsGrid {...others} />
        <button onClick={this.handleLoadMoreClick}>Load more</button>
      </div>
    );
  }
}

- extrait de "Blog BabelJS.org - React on ES6 +" par Steven Luscher

8
Mac Cowell