0

I found the solution I wanted and it works, see below.....

I know I am doing something stupid but I am having a mental block this morning and would appreciate some help. I am trying to construct html from a mapping:

In my render:

< ul>
  { arryItems.map(this.foo.bind(this)) }
< /ul>

Calling function:

foo(arry, i) {
 let result = '';

 if (arry.children != undefined && arry.children.length > 0) { 
    result= ( 
             <div key= {i}>{arry.name}
               {arry.children.map(function(child, ix){
                 <p key= {ix}>{child.name}</p>
               })}
             </div>
            )
  } else {
         result = (<div>{arry.name}</div>)
  }

   return result;
};

I am trying to return back html.

While I am receiving no error, the < p>{child.name}< /p> is not in the return html result.

Can anyone point out what is so blatantly obvious with my thinking that I cannot figure this out?

5
  • Just to note, you have i declared twice - one for you foo function, and another for your children map function. Commented Oct 14, 2015 at 13:00
  • Also, do you need the bind on the foo function? Commented Oct 14, 2015 at 13:03
  • Yea, I know, I'll change one so as not to confuse anyone, but still does not solve my issue. Commented Oct 14, 2015 at 13:03
  • Tom, it would be nice if you could provide the code. ;) Commented Oct 14, 2015 at 13:04
  • it could be worth you creating a jsFiddle with your code so we can see exactly what you've got. Commented Oct 14, 2015 at 13:09

2 Answers 2

1

So you want to render a component to an html string? React does this with renderToString. e.g:

var Task = React.createClass({
  render() {
    return (
      <li>{this.props.task.text}</li>
    );
  }
});

var Tasks = React.createClass({
  getTasks() {
    return [
      { _id: 1, text: 'This is task 1' },
      { _id: 2, text: 'This is task 2' },
      { _id: 3, text: 'This is task 3' }
    ];
  },

  renderTasks() {
    return this.getTasks().map(task => {
      return <Task key={task._id} task={task} />;
    });
  },

  render() {
    return (
        <ul>
          {this.renderTasks()}
        </ul>
    );
  }
});

var html = ReactDOMServer.renderToString(Tasks);

Note that since 0.14 this method has been split out to react-dom/server package, earlier versions it's just in the react package.

Sign up to request clarification or add additional context in comments.

3 Comments

What is wrong with my 'compact' way? I am getting no error, however, the element with the {child.name} is not in the return result. And what happens with your mapping of the children if their are no children?
@SarasotaSun can you give an example of how you are calling foo?
Updated my question above to reflect the calling of foo
0

I appreciate Dominic's help but I like my solution better, as it is compact and it checks if there are no children:

 foo(arry, index) {
    let children = this.getChildren(arry)
    return (
        <div key={index}>{arry.name}
            { children }
        </div>
    )
}

getChildren(arry){
    let result = [];
    if(arry.children != undefined && arry.children.length > 0){
         arry.children.map(function(child, ix){
             result.push(<p key={ix}>{child.name}</p>)
         })
    }
    return result;
}

render() {
   return (
       <section>
         { arryItems.map(this.foo.bind(this)) }
       </section>
   );
}

1 Comment

Compactness != better. I prefer Dominic's solution as it's far more readable. His solution could be tweaked slightly if there are no children.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.