146 votes

Quand devrais-je utiliser React.cloneElement vs this.props.children?

Je suis encore un noob à Réagir et, dans de nombreux exemples sur internet, je vois cette variation dans le rendu des éléments d'enfant que je trouve déroutant. Normalement, je vois ceci:

class Users extends React.Component {
  render() {
    return (
      <div>
        <h2>Users</h2>
        {this.props.children}
      </div>
    )
  }
}

Mais puis-je voir un exemple comme ceci:

<ReactCSSTransitionGroup
     component="div"
     transitionName="example"
     transitionEnterTimeout={500}
     transitionLeaveTimeout={500}
     >
     {React.cloneElement(this.props.children, {
       key: this.props.location.pathname
      })}
</ReactCSSTransitionGroup>

Maintenant, je comprends l'api, mais les docs n'est pas exactement clair quand je dois l'utiliser.

Alors, que peut-on faire pour les autres pas? Quelqu'un pourrait-il m'expliquer avec des exemples de meilleures?

254voto

Vennesa Points 360

props.children n'est pas le réel les enfants; C'est l' descriptor des enfants. Si vous n'avez pas fait quelque chose pour changer; vous ne pouvez pas changer des accessoires ou de modifier des fonctionnalités; vous pouvez seulement read from it. Si vous avez besoin de faire toutes les modifications que vous avez à créer new elements l'aide React.CloneElement.

https://egghead.io/lessons/react-use-react-cloneelement-to-extend-functionality-of-children-components

Un exemple:

principale fonction rendu d'un composant tel qu' App.js:

render() {   
    return(
            <Paragraph>
              <Sentence>First</Sentence>
              <Sentence>Second</Sentence>
              <Sentence>Third</Sentence>
            </Paragraph>   
    ) 
}

maintenant, disons que vous avez besoin pour ajouter un onClick pour chaque enfant de Paragraph; donc, dans votre Paragraph.js vous pouvez faire:

render() {
        return (
          <div>
          {React.Children.map(this.props.children, child => {
            return React.cloneElement(child, {
              onClick: this.props.onClick })   
         })}
         </div>
       ) 
}

ensuite, vous pouvez faire ceci:

render() {   
  return(
        <Paragraph onClick={this.onClick}>
          <Sentence>First</Sentence>
          <Sentence>Second</Sentence>
          <Sentence>Third</Sentence>
        </Paragraph>   
   ) 
}

Remarque: l' React.Children.map fonction seulement de voir l' top level - éléments, elle ne permet pas de voir toutes les choses que " les éléments de rendu, ce qui signifie que vous êtes fournissant directement des accessoires pour les enfants (ici l' <Sentence /> des éléments). Si vous avez besoin d'accessoires pour être transmis plus loin, disons que vous avez un <div></div> à l'intérieur de l'un de la <Sentence /> éléments qui veut utiliser l' onClick prop, alors dans ce cas vous pouvez utiliser l' Context API à le faire. Faire l' Paragraph le fournisseur et l' Sentence éléments en tant que consommateur.

74voto

Morten Olsen Points 1131

Tout d'abord, l' React.cloneElement exemple ne fonctionne que si votre enfant est un seul Réagir élément.

Pour presque tout, {this.props.children} est celui que vous voulez. Le clonage est utile dans certains des scénarios plus avancés, où un parent envoyer dans un élément et le composant enfant a besoin de changer quelques accessoires sur cet élément ou ajouter des choses comme ref pour l'accès au réel de l'élément DOM.

Dans l'exemple ci-dessus, le parent qui donne à l'enfant ne connaît pas l'exigence clé pour le composant, par conséquent, il crée une copie de l'élément, il est donné et ajouter une clé basée sur quelques identifiant unique de l'objet. Pour plus d'info sur ce que la clé n': https://facebook.github.io/react/docs/multiple-components.html

28voto

Xlee Points 1679

En fait, React.cloneElement n'est pas strictement lié aux this.props.children.

C'est utile lorsque vous avez besoin de cloner réagir éléments(PropTypes.element) pour ajouter/remplacer des accessoires, w/o vouloir le parent d'avoir des connaissances sur ces composants internes(e.g, fixation des gestionnaires d'événements ou d'affecter key/ref d'attributs).

Aussi réagir éléments sont immuables.

De réagir.cloneElement( élément, [accessoires], [...les] ) est presque équivalent à: <element.type {...element.props} {...props}>{children}</element.type>


Cependant, les enfants prop à réagir, est spécialement utilisé pour le confinement(aka composition), l'appariement avec React.Children de l'API et de l' React.cloneElement, composant qui utilise des accessoires.les enfants peuvent manipuler plus logique(e.g, les transitions de l'état, des événements, des DOM, des mesures, etc) à l'interne, tout en offrant le rendu de la partie à l'endroit où il est utilisé, de Réagir Routeur <switch/> ou partie de composé <select/> sont d'excellents exemples.

Une dernière chose qui vaut la peine de mentionner, c'est que réagir éléments ne sont pas limités à des accessoires.les enfants.

function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}

function App() {
  return (
    <SplitPane
      left={
        <Contacts />
      }
      right={
        <Chat />
      } />
  );
}

Ils peuvent être tout ce que les accessoires de sens, la clé a été de définir un bon contrat pour le composant, de sorte que les consommateurs peuvent être découplées de la sous détails de mise en œuvre, indépendamment du fait que c'est en utilisant React.Children, React.cloneElement, ou même React.createContext.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X