Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at CFUNITED 2010 (Landsdown, VA) with: Jude Lehman and Rachel Lehman
Ben Nadel at CFUNITED 2010 (Landsdown, VA) with: Jude Lehman@judewayne ) and Rachel Lehman@raelehman )

How JSX Renders Different Data Types In ReactJS

By Ben Nadel on

As a quick experiment, I wanted to see how JXS renders different types of data in ReactJS. And, think about how the rendering algorithm can be leveraged to generate conditional output. Of course, I am referring to "JSX" as the renderer. But really, JSX is just the syntactic sugar over the core ReactJS rendering engine. So, keep that in mind as you read this - I am using terms a bit loosely.


 
 
 

 
 
 
 
 

Run this demo in my JavaScript Demos project on GitHub.

To test the rendering of different data types, in JSX, I've put together a simple ReactJS app that passes different data values off to the "{ value }" syntax:

  • <!doctype html>
  • <html>
  • <head>
  • <meta charset="utf-8" />
  •  
  • <title>
  • How JSX Renders Different Data Types In ReactJS
  • </title>
  • </head>
  • <body>
  •  
  • <h1>
  • How JSX Renders Different Data Types In ReactJS
  • </h1>
  •  
  • <div id="content">
  • <!-- This content will be replaced with the React rendering. -->
  • </div>
  •  
  •  
  • <!-- Load scripts. -->
  • <script src="../../vendor/reactjs/react-0.13.3.min.js"></script>
  • <script src="../../vendor/reactjs/JSXTransformer-0.13.3.js"></script>
  • <script type="text/jsx">
  •  
  • // I manage the Demo widget.
  • var Demo = React.createClass({
  •  
  • // I render the component based on the current state.
  • render: function() {
  •  
  • var array = [ 1, 2, 3 ];
  •  
  • var object = {
  • name: "Winnie",
  • status: "Honey lover."
  • };
  •  
  • return(
  • <ul>
  • <li>
  • True: { true }
  • </li>
  • <li>
  • False: { false }
  • </li>
  • <li>
  • Number: { 4.5 }
  • </li>
  • <li>
  • Number(0): { 0 } { /* Testing for numeric Falsey values. */ }
  • </li>
  • <li>
  • String: { "Hello world!" }
  • </li>
  • <li>
  • Null: { null }
  • </li>
  • <li>
  • Array: { array }
  • </li>
  • <li>
  • Object: { object }
  • </li>
  • <li>
  • NaN: { ( "foo" * 3 ) }
  • </li>
  • <li>
  • Infinity: { ( 3 / 0 ) }
  • </li>
  • <li>
  • Undefined: { document.foo }
  • </li>
  • </ul>
  • );
  •  
  • }
  •  
  • });
  •  
  •  
  • // --------------------------------------------------------------------------- //
  • // --------------------------------------------------------------------------- //
  •  
  •  
  • // Render the root Demo and mount it inside the given element.
  • React.render( <Demo />, document.getElementById( "content" ) );
  •  
  • </script>
  •  
  • </body>
  • </html>

I'm trying to see not only how JSX renders different data types; but, also, how it renders different data values that can all be considered "Falsey" values. When we run this code, we get the following browser output:


 
 
 

 
 Looking at how JSX renders different data types in ReactJS. 
 
 
 

There are a number of interesting behaviors going on here:

  • True, False, Null, and Undefined (sorry, not in the demo) values are not rendered.
  • Each value of an Array is rendered individually.
  • Each key-value pair of an object is rendered individually.

Off-hand, I can't think of a use-case of Object rendering (yet); but, Array rendering is quite core to the way ReactJS works. Typically, we see Array rendering when a collection of data points are mapped (using ES5's .map() method) onto a collection of React Elements. But, we can also use Array rendering to render inline collections of mixed data, as seen in the documentation:

{ [ variableA, <span> &mdash; </span>, variableB ] }

But, the feature that I really want to look at is the non-rendering of False. Since JSX, and ReactJS, don't render False values, it means that we can leverage the logical AND operator to conditionally output string values.

To demonstrate this, I'm going to render a list of friends where each friend may be a BFF (Best Friends Forever, yo!). If a particular friend is a BFF, I want to render some additional output:

  • <!doctype html>
  • <html>
  • <head>
  • <meta charset="utf-8" />
  •  
  • <title>
  • Leverage Truthy JSX Rendering For Conditional Output In ReactJS
  • </title>
  • </head>
  • <body>
  •  
  • <h1>
  • Leverage Truthy JSX Rendering For Conditional Output In ReactJS
  • </h1>
  •  
  • <div id="content">
  • <!-- This content will be replaced with the React rendering. -->
  • </div>
  •  
  •  
  • <!-- Load scripts. -->
  • <script src="../../vendor/reactjs/react-0.13.3.min.js"></script>
  • <script src="../../vendor/reactjs/JSXTransformer-0.13.3.js"></script>
  • <script type="text/jsx">
  •  
  • // I manage the Demo widget.
  • var Demo = React.createClass({
  •  
  • // I render the component based on the current state.
  • render: function() {
  •  
  • // With this collection of friends, there is an "isBFF" flag that we want
  • // to use to conditionally render some additional output.
  • var friends = [
  • {
  • id: 1,
  • name: "Joanna",
  • isBFF: false
  • },
  • {
  • id: 2,
  • name: "Kim",
  • isBFF: true
  • },
  • {
  • id: 3,
  • name: "Sarah",
  • isBFF: false
  • }
  • ];
  •  
  • // Map the friends onto LI elements.
  • var listItems = friends.map(
  • function iterator( friend, i ) {
  •  
  • return(
  • <li key={ friend.id }>
  • { friend.name }
  • {
  • // Notice that we can leverage Truthy / Falsey
  • // rendering, in JSX, to conditionally render a string
  • // based on a logical outcome. Since JSX will not
  • // render [false], then any condition that results in
  • // [false] will not be rendered. However, in JavaScript,
  • // the [&&] and [||] operators will return the last
  • // evaluated value in the condition, which in our case,
  • // is the string that we want to render.
  • // --
  • // CAUTION: If [isBFF] is a number, like "0", then it
  • // will be rendered since JSX will render Falsey numbers.
  • }
  • { friend.isBFF && " \u2014 Oh man, she's the best!" }
  • </li>
  • );
  •  
  • }
  • );
  •  
  • return(
  • <ul>
  • { listItems }
  • </ul>
  • );
  •  
  • }
  •  
  • });
  •  
  •  
  • // --------------------------------------------------------------------------- //
  • // --------------------------------------------------------------------------- //
  •  
  •  
  • // Render the root Demo and mount it inside the given element.
  • React.render( <Demo />, document.getElementById( "content" ) );
  •  
  • </script>
  •  
  • </body>
  • </html>

Run this demo in my JavaScript Demos project on GitHub.

Notice that "friend.isBFF" is being used to drive the conditional output. And, when we run the above code, we get the following output:

  • Joanna
  • Kim -- Oh man, she's the best!
  • Sarah

If you look in the above code, you'll notice that I have to encode the mdash as the unicode character \u2014. This is required because HTML, within a string, will be escaped. To get around this somewhat awkward and unreadable notation, we can actually leverage the same behavior to conditionally output full-fledged React Elements, not just string values. This time, rather than AND'ing the isBFF flag with a string, we're going to AND it with a React Element:

  • <!doctype html>
  • <html>
  • <head>
  • <meta charset="utf-8" />
  •  
  • <title>
  • Leverage Truthy JSX Rendering For Conditional Output In ReactJS
  • </title>
  • </head>
  • <body>
  •  
  • <h1>
  • Leverage Truthy JSX Rendering For Conditional Output In ReactJS
  • </h1>
  •  
  • <div id="content">
  • <!-- This content will be replaced with the React rendering. -->
  • </div>
  •  
  •  
  • <!-- Load scripts. -->
  • <script src="../../vendor/reactjs/react-0.13.3.min.js"></script>
  • <script src="../../vendor/reactjs/JSXTransformer-0.13.3.js"></script>
  • <script type="text/jsx">
  •  
  • // I manage the Demo widget.
  • var Demo = React.createClass({
  •  
  • // I render the component based on the current state.
  • render: function() {
  •  
  • // With this collection of friends, there is an "isBFF" flag that we want
  • // to use to conditionally render some additional output.
  • var friends = [
  • {
  • id: 1,
  • name: "Joanna",
  • isBFF: false
  • },
  • {
  • id: 2,
  • name: "Kim",
  • isBFF: true
  • },
  • {
  • id: 3,
  • name: "Sarah",
  • isBFF: false
  • }
  • ];
  •  
  • // Map the friends onto LI elements.
  • var listItems = friends.map(
  • function iterator( friend, i ) {
  •  
  • {
  • // Rather than using the logical AND operator to output a
  • // simple string value, we're going to use it to conditionally
  • // output a React Element.
  • }
  • var bffElement = ( <span> &mdash; Oh man, shes the best!</span> );
  •  
  • return(
  • <li key={ friend.id }>
  • { friend.name }
  • { friend.isBFF && bffElement }
  • </li>
  • );
  •  
  • }
  • );
  •  
  • return(
  • <ul>
  • { listItems }
  • </ul>
  • );
  •  
  • }
  •  
  • });
  •  
  •  
  • // --------------------------------------------------------------------------- //
  • // --------------------------------------------------------------------------- //
  •  
  •  
  • // Render the root Demo and mount it inside the given element.
  • React.render( <Demo />, document.getElementById( "content" ) );
  •  
  • </script>
  •  
  • </body>
  • </html>

Run this demo in my JavaScript Demos project on GitHub.

Running this produces the output as above. This, to me, is very exciting because I think this entire concept of AND-based conditional output can be used to greatly simplify some of the rendering techniques. Rather than conditionally defining a value, you can always define it; then, just render it under certain conditions.

Sometimes, when you look at demos, it's easy to lose sight of what is going on. By stepping back and looking at how JSX and ReactJS render different data types, I think it can give us more insight into the process and, therefore, more opportunity to control how rendering takes place in our ReactJS components.




Reader Comments

Really cool and helpful. Without understanding the underlying behavior, ` { bool && element }` isn't very intuitive. I could see it being quite confusing for someone looking at the code for their first time. Without your explanation, I would have expected a true/false output. Thanks @Ben.

Reply to this Comment

@Josh,

Yeah, I think you're right. This is definitely not very intuitive. But, there is something nice about it. I think once you get used to the concept, it can make the code easier to reason about.

Reply to this Comment

@All,

Just came across this in the "Tips" documentation for React:

http://facebook.github.io/react/tips/false-in-jsx.html

It looks like this is exactly why they don't render False/Null values -- to be able to enable the "&&" approach to rendering. So, at least they are intentful about it.

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.