Skip to content
Advertisement

React – How can I strip top level div from a React.Component

When writing JSX, I sometimes need to create a top level element so the code will compile. For example, this won’t compile.

const routesList1 = (
    <Route exact path="/link1" component={Link1UI}/>
    <Route exact path="/link2" component={Link2UI}/>
)

But this will:

const routesList1 = (
  <div>
    <Route exact path="/link1" component={Link1UI}/>
    <Route exact path="/link2" component={Link2UI}/>
  </div>
)

Usually wrapping other React elements in a <div> works fine, but not always. So I’d like to know if I was forced to create a top level element to get the code to compile, can I later strip it off? If so how?

Below is a conceptual example of a problem I ran into with React router’s Switch element.

import react from 'react';
import { Route, Switch } from 'react-router-dom';

const routesList1 = (
  <div>
    <Route exact path="/link1" component={Link1UI}/>
    <Route exact path="/link2" component={Link2UI}/>
  </div>
)

const routesList2 = (
  <div>
    <Route exact path="/link3" component={Link3UI}/>
    <Route exact path="/link4" component={Link4UI}/>
  </div>
)

function stripDivFrom(reactElement) {
    reactElement.Children.toArray();
}

class MyApp extends React.Component {
    render() {
        return (
            <Switch>
                {stripDivFrom(routesList1)}
                {stripDivFrom(routesList2)}
                <Route exact path="/help" component={HelpUI}/>
            </Switch>
        );
    }
}

I provide this simplified example code so readers can understand what I’m asking.

I’m looking to get an answer to the question, not for a work around.

The question is: How can I get the children of a given react/JSX element? How can I change the stripDivFrom() function so that it works.

NOTE: The stripDivFrom() function currently doesn’t work. The Children property doesn’t is undefined (when I observe it in Chrome debugger). I found it when looking at the React source code but I’m obviously misunderstanding something. The browser console has an error that says: Uncaught TypeError: Cannot read property ‘toArray’ of undefined.

Updated

EDITED: After this question was asked, in React introduced a better solution to this problem.

In React 16.2.0 the component <React.Fragment> was added which solves this problem.

The following is how the code would now loook:

    const routesList1 = (
      <React.Fragment>
        <Route exact path="/link1" component={Link1UI}/>
        <Route exact path="/link2" component={Link2UI}/>
      </React.Fragment>
    )

Advertisement

Answer

It will be available by element.props.children.

Write it like this:

function stripDivFrom(reactElement) {
    return reactElement.props.children;
}

What is props.children in react?

In JSX expressions that contain both an opening tag and a closing tag, the content between those tags is passed as a special prop: props.children.

React elements are basically objects, check this example:

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

Object created by react will be:

const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world'
  }
};

Check this: JSX Represents Objects

Working Code (style on wrapper div will not reflect in ui):

const hello = <div style={{color:'red'}}><div>Hello</div><div>World</div></div>

class Game extends React.Component {

  a(el){
    return el.props.children;
  }
  
  render() {
    return (
      <div id="game-layout">
        {this.a(hello)}
      </div>
    );
  }
}

ReactDOM.render(
  <Game/>,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id ='container'/>

working Fiddle: https://jsfiddle.net/mayankshukla5031/0cwueg7j/

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement