128
votes

Today I have started learning ReactJS and after an hour faced with the problem.. I want to insert a component which has two rows inside a div on the page.A simplified example of what I am doing below.

I have an html:

<html>
..
  <div id="component-placeholder"></div>
..
</html>

Render function like this:

...
render: function() {

    return(
        <div className="DeadSimpleComponent">
            <div className="DeadSimpleComponent__time">10:23:12</div >
            <div className="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
        </div>
    )
}
....

And below I am calling render:

ReactDOM.render(<DeadSimpleComponent/>, document.getElementById('component-placeholder'));

Generated HTML looks like this:

<html>
..
  <div id="component-placeholder">
    <div class="DeadSimpleComponent">
            <div class="DeadSimpleComponent__time">10:23:12</div>
            <div class="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
    </div>
</div>
..
</html>

The problem that I am not a very happy that React forcing me to wrap all in a div "DeadSimpleComponent". What is the best and simple workaround for it, without explicit DOM manipulations?

UPDATE 7/28/2017: Maintainers of React added that possibility in React 16 Beta 1

Since React 16.2, you can do this:

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}
10
perfect naming practice ;-)Kirill Reznikov
Could I see your HTML file? I mis-read your question. I may have a workaround though.Louis93
You have a problem with a component having a single element? Really?Dominic
What do you mean? I am just trying React, it should not be very complicated.. But limitation looks annoying.Kirill Reznikov

10 Answers

159
votes

This requirement was removed in React version (16.0)]1, so now you are able to avoid that wrapper.

You can use React.Fragment to render a list of elements without creating a parent node, official example:

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

More here: Fragments

62
votes

Update 2017-12-05: React v16.2.0 now fully supports rendering of fragments with improved support for returning multiple children from a components render method without specifying keys in children:

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}

If you are using a React version prior to v16.2.0, it is also possible to use <React.Fragment>...</React.Fragment> instead:

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

Original:

React v16.0 introduced returning an array of elements in render method without wrapping it in a div: https://reactjs.org/blog/2017/09/26/react-v16.0.html

render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}

At the moment, a key is required for each element to avoid the key warning but this could be changed in future releases:

In the future, we’ll likely add a special fragment syntax to JSX that doesn’t require keys.

6
votes

You can use:

render(){
    return (
        <React.Fragment>
           <div>Some data</div>
           <div>Som other data</div>
        </React.Fragment>
    )
}

For further details refer to this documentation.

5
votes

Use [], instead of ()'s to wrap the entire return.

render: function() {
  return[
    <div className="DeadSimpleComponent__time">10:23:12</div >
    <div className="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
  ]
}
2
votes

I created a component to wrap child components without a DIV. It's called a shadow wrapper: https://www.npmjs.com/package/react-shadow-wrapper

1
votes

This is still required, BUT React now make sure to create elements without creating an additional DOM element.

The extra wrapping needed (normally with a parent div) because Reacts createElement method require a type parameter which is either a tag name string (such as 'div' or 'span'), a React component type (a class or a function). But this was before they introduce React Fragment.

Refer this NEW api doc for createElement

React.createElement : Create and return a new React element of the given type. The type argument can be either a tag name string (such as 'div' or 'span'), a React component type (a class or a function), or a React fragment type.

here is the official example, Refer React.Fragment.

render() {
  return (
    <React.Fragment>
      Some text.
      <h2>A heading</h2>
    </React.Fragment>
  );
}
0
votes

You won't be able to get rid of that div element. React.render() needs to return one valid DOM node.

0
votes

Here is one way to render "transculent" components:

import React from 'react'

const Show = (props) => {
  if (props.if || false) {
    return (<React.Fragment>{props.children}</React.Fragment>)
  }
  return '';
};

----


<Show if={yomama.so.biq}>
    <img src="https://yomama.so.biq">
    <h3>Yoamama</h3>
<Show>

enter image description here

0
votes

There is workaround too. The below block code generates fragment without the need of React.Fragment.

return [1,2,3].map(i=>{
if(i===1) return <div key={i}>First item</div>
if(i===2) return <div key={i}>Second item</div>
return <div key={i}>Third item</div>
})
0
votes

I know this question has been answered, you can of course use React.Fragment which doesn't create a node but let's you group stuff like a div.

Additionally if you want to have fun you can implement (and learn lots of things) a React mode that removes the extra div's and for this I really want to share a great video on how you can do it on the react code base itself.

https://www.youtube.com/watch?v=aS41Y_eyNrU

This is of course not something that you would do in practice but it's a good learning opportunity.