React: Feature Request: Allow Fragments to accept the className prop

Created on 18 May 2018  路  3Comments  路  Source: facebook/react

Use case:

A set of elements should be wrapped in a <div> (with a class), but only depending on certain scenarios.

Example:

Test Component
import * as React from 'react';

class Test extends React.Component {
    render() {
        const Wrapper = this.props.wrap ? 'div' : React.Fragment;

        return (
            <Wrapper className={'wrapper'}>
               <div>Child 1</div>
               <div>Child 2</div>
            </Wrapper>
        );
    }
}

export default Test;
Scenario 1
<Test />
<div>Child 1</div>
<div>Child 2</div>
Scenario 2
<Test wrap={true} />
<div class="wrapper">
    <div>Child 1</div>
    <div>Child 2</div>
</div>

Even though the above examples will actually output the way they are intended, an error is still being thrown:

image

Solution:

Allow the className prop on Fragments, but simply ignore it, don't do anything with it.

Of course there are many other way this can be achieved without using Fragments, but I think this approach is really clean.

Most helpful comment

DOM property should only be added to the actual nodes but Fragments don't map to any.

In this case, I would suggest you to do this in the render function:

const { wrap, children } = this.props;
return (
  wrap ?
    <Wrapper className="foo">
      {children}
    </Wrapper>
    :
    <>
      {children}
    </>
);

which is clean and intuitive enough.

All 3 comments

why you can't use another variable for wrapper template? I mean why you can't just write:

import * as React from 'react';

class Test extends React.Component {
    render() {
        const div = <div className="wrapper"></div>;
        const Wrapper = this.props.wrap ? div : React.Fragment;

        return (
            <Wrapper className={'wrapper'}>
               <div>Child 1</div>
               <div>Child 2</div>
            </Wrapper>
        );
    }
}

export default Test;

P.S. Why you use this form of import React:

import * as React from 'react';

instead

import React from 'react';

I just be interested

DOM property should only be added to the actual nodes but Fragments don't map to any.

In this case, I would suggest you to do this in the render function:

const { wrap, children } = this.props;
return (
  wrap ?
    <Wrapper className="foo">
      {children}
    </Wrapper>
    :
    <>
      {children}
    </>
);

which is clean and intuitive enough.

I think @cyan33's solution is the best workaround for your use case. Adding DOM attributes to a Fragment would probably be confusing to most people.

Was this page helpful?
0 / 5 - 0 ratings