Ad

Append To Existing JSX Instead Of Using If-else Conditional Logic

- 1 answer

In my react classes, I often find myself having to use conditional logic to decide what to render. The problem with such an approach is that it leads to a lot of redundant markup. Here is an example:

if(this.props.quotes) {
    return (
        <div className="card">
            <div className="item-1">{this.props.header}</div>
            <div className="item-2">Add content...</div>
            <i className="fa fa-quote-left"></i>
            <i className="fa fa-quote-right"></i>
        </div>
    );
}
else {
    return (
        <div className="card">
            <div className="item-1">{this.props.header}</div>
            <div className="item-2">Add content...</div>
        </div>
    );
}

The only difference between the two HTML components is that one has two extra font-awesome elements. Ideally, you would want to use some base markup, and append content to it based on the result of the conditional.

I tried the following approach where I put the HTML content into an array and pushed the extra HTML elements in if the condition this.props.quotes was met:

var cardContent = [
    <div className="item-1">{this.props.header}</div>, 
    <div className="item-2">Add content...</div>
];

if(this.props.quotes) {
    cardContent.push(<i className="fa fa-quote-left"></i>);
    cardContent.push(<i className="fa fa-quote-right"></i>);
}

return (
    <div className="card">
        {cardContent}
    </div>
);

This introduces a new problem, mainly that React complains about missing key props in the array:

Warning: Each child in an array or iterator should have a unique "key" prop.

In this context, it doesn't make sense to give the elements keys since 3/4 of the content is static (the only non-static element is {this.props.header}).


Is there a better way of appending to existing JSX than the method I outlined above? I don't want to suppress all unique key prop warnings since it is still valid in the case of mapping. Is it better to just accept the redundant HTML approach?

Ad

Answer

When you render an Array of JSX elements, each one must have a key property on them. As you construct your array, you can do something like

cardContent.push(<div className="item-1" key="item-1">..</div>)
cardContent.push(<div className="item-2" key="item-2">..</div>)

I also want to mention for the example you've described, your elements are simple enough that having an inline condition rather than having two blocks that you conditionally return

return (
  <div className="card">
    <div className="item-1">{this.props.header}</div>
    <div className="item-2">Add content...</div>
    {this.props.quotes && <i className="fa fa-quote-left"></i>}
    {this.props.quotes && <i className="fa fa-quote-right"></i>}
  </div>
)
Ad
source: stackoverflow.com
Ad