First solution (edit: alternative)
render() {
const statement = true;
const stuff = this.buildStuff(statement, 3); // jsx result looped in divs
return (
<div>
{
statement &&
<div>
{ stuff }
</div>
}
</div>
);
}
Alternative, memoization (caching of functions) if this is your goal:
const memoize = require('fast-memoize');
const memoized = memoize(this.buildStuff);
...
render() {
const statement = true;
return (
<div>
{
statement &&
<div>
<p>
{memoized()}
</p>
<p>
{memoized()}
</p>
<p>
{memoized()}
</p>
</div>
}
</div>
);
}
The true power of memoization however is, if you cache based on the parameter you give to buildStuff (maybe you move statement into buildstuff?). In your case I would just clean up the component and parameters in favour of readability rather than optimising something. So last alternative:
// Stuff is a component now
const Stuff = ({statement, stuff}) => {
if(!statement)
return null;
const result = stuff();
return (
<div>
<p>
{result}
</p>
<p>
{result}
</p>
<p>
{result}
</p>
</div>
)
}
render() {
return (
<div>
<Stuff statement={true} stuff={this.buildStuff} />
</div>
);
}
The benefit, you can now choose to pass the result or the function itself through props, and in the downward component either call the function or simply have its results passed through.
Single answer to your question in the headline: you cant, JSX is not a templating engine like Razor.
Explanation:
// JSX
<div id="foo">Hello world</div>
// Translates into
React.createElement("div", {id: "foo"}, "Hello world");
// JSX
<div>{ statement && <div /> }</div>
// Translates to
React.createElement("div", null, statement && React.createElement("div"));
Either you declare a new variable with an attribute, or you simply cant, since javascript does not allow variable creation inside parameters of functions.