27

Can you use a if statement in JSX like this?

    var chartGraphContent =
        <div className={"chartContent"}>
            if(this.state.modalityGraph['nca'] > 0){
                <div className={"chart-container"}>
                    <Chart
                        chartType="ColumnChart"
                        data = { this.state.modalityGraph?this.state.modalityGraph.chartData['units']:emptyDataRows }
                        options={chartOptions}
                        graph_id="modalitiesChart"
                        width="100%"
                        height="250px"
                    /> 
                </div>
            }
        </div>;

Something like above? Is it possible to have JSX based on a condition?

4
  • JSX needs a block scope {} to parse Javascript. You can use ternary operator as { this.state.modalityGraph[]>0 ? <div/> : null } Commented Sep 11, 2017 at 13:32
  • this is a section inside the jsx block Commented Sep 11, 2017 at 13:33
  • Check out the docs, react-cn.github.io/react/tips/if-else-in-JSX.html Commented Sep 11, 2017 at 13:34
  • This might help: stackoverflow.com/questions/41531950/… Commented Sep 11, 2017 at 13:35

4 Answers 4

33

Use conditional rendering, and since you have no else-case, you can use && instead of a ternary operator for brevity:

It works because in JavaScript, true && expression always evaluates to expression, and false && expression always evaluates to false.

Therefore, if the condition is true, the element right after && will appear in the output. If it is false, React will ignore and skip it.

Thus:

   <div className={"chartContent"}>
        {this.state.modalityGraph['nca'] > 0 &&
            <div className={"chart-container"}>
                <Chart
                    chartType="ColumnChart"
                    data = { this.state.modalityGraph?this.state.modalityGraph.chartData['units']:emptyDataRows }
                    options={chartOptions}
                    graph_id="modalitiesChart"
                    width="100%"
                    height="250px"
                /> 
            </div>
        }
    </div>

This will only render JSX if a condition is true. If it is false, React won't render anything. Remember, you have to wrap inline JavaScript expressions in JSX with { … }, you can't just have it inside JSX.

Using if/else statements directly in JSX will cause it to be rendered literally as text, which isn't desired. You also can't use them in inline JavaScript expressions because if statements are not expressions, so this won't work:

{
  if(x) y
}
Sign up to request clarification or add additional context in comments.

3 Comments

What if value is 0. What will it print? false?
I have never tried this, so thought of confirming. I always like to use a ternary operator { condition ? jsx : null }
@Rajesh Falsey values in expressions are never rendered except for 0 IIRC.
10

As per DOC:

if-else statements don't work inside JSX. This is because JSX is just syntactic sugar for function calls and object construction.


We can't use if-else statement or any other statement directly inside JSX, only expressions are allowed.

Expressions inside JSX:

Wou can embed any JavaScript expression in JSX by wrapping it in curly braces.

To put any expression we need to use {}, so instead of if use && operator or ternary operator for conditional rendering.

By using ternary operator:

var chartGraphContent =
<div className={"chartContent"}>
    {
        this.state.modalityGraph['nca'] > 0 ?
            <div className={"chart-container"}>
                <Chart
                    chartType="ColumnChart"
                    data = { this.state.modalityGraph?this.state.modalityGraph.chartData['units']:emptyDataRows }
                    options={chartOptions}
                    graph_id="modalitiesChart"
                    width="100%"
                    height="250px"
                /> 
            </div>
        :null
    }
</div>;

By using && operator:

var chartGraphContent =
<div className={"chartContent"}>
    {
        this.state.modalityGraph['nca'] > 0 &&
            <div className={"chart-container"}>
                <Chart
                    chartType="ColumnChart"
                    data = { this.state.modalityGraph?this.state.modalityGraph.chartData['units']:emptyDataRows }
                    options={chartOptions}
                    graph_id="modalitiesChart"
                    width="100%"
                    height="250px"
                /> 
            </div>
    }
</div>;

Comments

5

Better to use with ternary Operator, By doing so you can also add else block to your code.

Try this:

var chartGraphContent =
        <div className={"chartContent"}>
            {this.state.modalityGraph['nca'] > 0 ?
                <div className={"chart-container"}>
                    <Chart
                        chartType="ColumnChart"
                        data = { this.state.modalityGraph?this.state.modalityGraph.chartData['units']:emptyDataRows }
                        options={chartOptions}
                        graph_id="modalitiesChart"
                        width="100%"
                        height="250px"
                    /> 
                </div>
                : "<span>Else Block</span>"
            }
        </div>;

Update (Another method)

and in case for more complex and large condition you can call inline functions too to return your template , in this way you can avoid your code to become messy. here is an example.

var ifBlockCode = function ifBlockCode(){
    return (
        <div className={"chart-container"}>
            <Chart
                chartType="ColumnChart"
                data = { this.state.modalityGraph?this.state.modalityGraph.chartData['units']:emptyDataRows }
                options={chartOptions}
                graph_id="modalitiesChart"
                width="100%"
                height="250px"
            /> 
        </div>
    )
}

var elseBlockCode = function elseBlockCode(){
    return (
        <span>Else Block</span>
    )
}
var chartGraphContent =
<div className={"chartContent"}>
    {this.state.modalityGraph['nca'] > 0 ?
        {this.ifBlockCode} : {this.elseBlockCode}
    }
</div>;

Comments

0

To work around the limitation that JSX supports expressions only: (if control blocks are statements)

  • Just use multiple return statements wrapped by your control block.

The keyword return introduces a statement. You can simply wrap you JSX logic into control structure scopes, where each case is its own return statement (nobody ever said you can't use two return statements!)

if (case) {
  return <JSX prop=true/>
else {
  return <JSX prop=false/>
}

Side note about expressions vs statements

Expressions must be pure, which is probably why JSX (function calls) accept them. The if-blocks are not pure in the sense that they can introduce side effects (they can wrap multiple expressions, some of which must have nothing to do with the resulting value). Expressions cannot do this because they must return a value. In that sense, they are pure. They could introduce effects, but these would be effects and not side effects.

e.g. this silly example of an expression that has effects but I would argue that they are not side effects because the expression does exactly one thing in each case.

const a: void = v ? console.log("a") : console.log("b");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.