Reputation: 35797
Normally if you have something like:
<SomeComponent foo={bar} />
you can make it optional by using a ternary:
{bar ? <SomeComponent foo={bar} /> : null}
But what if the block you are starting with contains a component plus some text (a single space) and a variable, e.g.:
<SomeComponent foo={bar} /> {foobar}
Wrapping it in parentheses won't work:
{bar ? (<SomeComponent foo={bar} /> {foobar}) : null}
and in fact the only way I found to make it work was to wrap everything in another element:
{bar ? <span><SomeComponent foo={bar} /> {foobar}</span> : null}
Is there any other way to tell React that:
<SomeComponent foo={bar} /> {foobar}
is a discrete chunk, so that I can use it in a ternary (inside JS, not JSX, logic) ... without adding meaningless wrapper elements?
Upvotes: 7
Views: 3299
Reputation: 2197
There used to be two suboptimal ways to achieve this:
Using an array, which requires adding keys to React elements:
{bar ? [<SomeComponent key="1" foo={bar} />, " ", foobar] : null}
But with React 16.2.0+ you can use improved fragments:
{bar ? <React.Fragment><SomeComponent foo={bar} /> {foobar}</React.Fragment> : null}
or, even better, you can use the shorthand syntax:
{bar ? <><SomeComponent foo={bar} /> {foobar}</> : null}
Fragments won't produce an additional container element.
Upvotes: 8
Reputation: 2781
You could define a small component that would act as a wrapper but won't render any markup, but it technically is still a wrapper. I use this approach by defining Aux
component:
const Aux = (props) => (props.children);
Then you can do:
{bar ? <Aux><SomeComponent foo={bar} /> {foobar}</Aux> : null}
This at least avoids unnecessary markup in the resulting html
which might be crucial for styling purposes, if you are using flex-box
for example.
Upvotes: 2