web-dev-qa-db-fra.com

comment rendre les composants enfants dans react.js récursivement

Je voulais ajouter récursivement un composant React à partir de son propre composant. J'ai vu cet exemple d'un composant d'arbre qui mappait à travers les TreeNodes enfants et ajoutait des nœuds enfants de la même manière. Malheureusement, cela ne fonctionne pas du tout pour moi. L'idée était d'avoir un simple composant de commentaire, et les réponses réutiliseraient le même composant.

var Comment = React.createClass({
  render: function() {    
    return (
        <div className="comment">

          {/* text and author */}
          <div className="comment-text">
            <span className="author">{this.props.author}</span>         
            <span className="body" dangerouslySetInnerHTML={{__html: this.props.body}} />
          </div>

          {/* replies */}
          <div className="replies">
           {
             this.props.replies.map(function(reply) {
               <Comment body={reply.body} author={reply.author} />
             }.bind(this))
          }
          </div>

      </div>
    );
  }
});

Je reçois le message d'erreur suivant:

TypeError non capturé: Échec de la construction de 'Commentaire': Veuillez utiliser l'opérateur 'nouveau', ce constructeur d'objet DOM ne peut pas être appelé en tant que fonction.

voici un exemple des données JSON transmises au composant.

{ "author" : "Some user",
  "body" : "<div>Great work</div>",
  "replies" : [ { "author" : "A user replying",
        "body" : "<div Yes it was great work</div>"
      },
      { "author" : "Another user replying",
        "body" : "<div It really was great work!</div>"
      }
    ]
}
38
svnm

Si je crée les nœuds enfants en tant qu'objet en haut de la méthode de rendu, cela fonctionne très bien.

export default class extends React.Component {
  let replies = null
  if(this.props.replies){
    replies = this.props.replies.map((reply) => {
      return (
        <Comment author={reply.author} body={reply.body} />
      )
    })
  }

  render() {
    return (
      <div className="comment">
        <div className="replies">{ replies }</div>
      </div>
    )
  }
}
14
svnm

Voici une alternative dans ES6:

import React, { Component, PropTypes } from 'react'

export default class Comments extends Component {

  render() {

    const { children } = this.props

    return (
      <div className="comments">
        {children.map(comment =>
          <div key={comment.id} className="comment">
            <span>{comment.content}</span>
            {comment.children && <Comments children={comment.children}/>}
          </div>
        )}
      </div>
    )

  }

}

Comments.propTypes = {
  children: PropTypes.array.isRequired
}

Et est un autre composant:

<Comments children={post.comments}/>
40
Francisco Aquino

La façon la plus simple est de créer une fonction dans la classe qui retourne une instance de votre classe:

RecursiveComponent.rt.js:

var RecursiveComponent = React.createClass({
 render: function() {
  // JSX
  ....
 },
 renderRecursive: function(param1)
   return React.createElement(RecursiveComponent, {param1: param1});

});

si vous utilisez bibliothèque react-templates :

RecursiveComponent.rt:

<div>
  ...
  <div rt-repeat="recursiveChild in this.props.recursiveItem.recursiveChilds">
            {this.renderRecursive(recursiveChild)}
  </div>
</div>
1
maimArt