Gijo Varghese
Gijo Varghese

Reputation: 11780

Props vs Children to pass HTML content in ReactJS

I need create a component to render like this:

<div class="row">
    <div class="col">
        <div class="some another class">
            <h3>{{title}}</title>
        </div>
    </div>
    <div class="col">
        <p>{{contentA}}</p>
    </div>
    <div class="row">
        <div class="some wrapper">
            <p>{{contentB}}</p>
        <div>
    </div>
<div>

It will receive the following data:

Here are the following methods I found. However, I'm not sure about which one is the recommended way by React.

Method 1

<Component title="a" contentA="some large content" contentB="another large content"/>

Pros: Easy to access different props in different sections of the component

Cons: Too complex to handle if the content as large HTML content

Method 2

<Component>
    <title>a</title
    <content>some large content</content>
    <content>another large content</content>
</Component>

Pros: Much simpler code

Cons: Need to filter props.children and find each element to put in correct place in the component

Upvotes: 1

Views: 2652

Answers (2)

Praveen Rao Chavan.G
Praveen Rao Chavan.G

Reputation: 2860

React is all about creating granular components, the more granular you component tree is, you are doing it the more React way.

You say you get 3 things text,contentA and ContentB

Title: it's already granular.

content A: You say its a "a large string (paragraph), may container links (a href)" , if its a paragraph it is granular but if its a collection of paragraphs, I think you should take that to a different component. Ex: ContentA component

Content B: This is clearly said that its a complex HTML code, that is what is React for, you need to break this complex HTML code into granular components which will make it more maintainable and it is a React best practice too.

have patience while breaking this into components, it's definitely worth it.

hope that helps.

Upvotes: 2

Adam Nathaniel Davis
Adam Nathaniel Davis

Reputation: 425

This is not really an accurate statement:

Cons: Too complex to handle if the content as HTML contents

If a value can be held in a variable as a string, it can be used as an argument passed into your component. If you don't want to be bothered trying to escape the quotes inside your prop values, I would encourage you to ditch the <Component attr="someValue"/> syntax and instead use <Component attr={'someValue'}/>. This allows you to pass variables into your props. This also allows you to use template literals to pass values, like so:

<Component
    title="a"
    contentA={`
        <html>
            <head></head>
            <body>
                <p>Here is my super-big</p>
                <p>HTML-infused content</p>
                <p>I can even inject ${variables} in here!</p>
            </body>
        </html>
    `} 
    contentB="another large content"
/>

If you feel like that starts to clutter-up the declaration of your component, you can instead set those values in a variable and then pass them very cleanly into the component, as such:

render() {
    const bigHtmlContent = (
        <html>
            <head></head>
            <body>
                <p>Here is my super-big</p>
                <p>HTML-infused content</p>
                <p>I can even inject {variables} in here!</p>
            </body>
        </html> 
    );
    return (
        <Component
            title="a"
            contentA={bigHtmlContent} 
            contentB="another large content"
        />  
    );
}

Of course, you can move the definition out of the render() function altogether if that suits you better:

getBigHtmlContent() {
    return (
        <html>
            <head></head>
            <body>
                <p>Here is my super-big</p>
                <p>HTML-infused content</p>
                <p>I can even inject {variables} in here!</p>
            </body>
        </html>     
    );
}

render() {
    return (
        <Component
            title="a"
            contentA={() => this.getBigHtmlContent()} 
            contentB="another large content"
        />  
    );
}

When I'm creating components, I tend to pass everything as props (as shown in the examples above). I only use children if I'm creating a higher-order component which, by design, is supposed to act as a container for certain types of children.

For example, in Material UI there is a <List> component which requires one-or-more <ListItem>s. In that case, I don't think it would make much sense to pass the <ListItems>s as props. They are (and should be) children of the <List> component.

Upvotes: 2

Related Questions