Home

React - JSX Intro

JSX files have a .js extension

and need, at the top of the file...

import React from 'react';
import ReactDOM from 'react-dom';


This is explained a little more on the React Components page.

Attributes

JSX elements can have attributes, just like HTML elements can.
A JSX attribute is written using HTML-like syntax: a name, followed by an equals sign, followed by a value.
The value should be wrapped in quotes, like this:-

my-attribute-name="my-attribute-value"

Here are some JSX elements with attributes...

<a href='http://www.example.com'>Welcome to the Web</a>

const title = <h1 id='title'>Introduction to React.js: Part I</h1>;


A single JSX element can have many attributes, eg...

const panda = <img src='images/panda.jpg'
   alt='panda'
   width='500px'
   height='500px' />

class vs className

Because the word class is a reserved word if you need to specify the class as an attribute you will have to change it to className, eg...

const title = <h1 className='myClass' id='title'> Introduction to React.js: Part I</h1>;

JSX Expression

A JSX expression can only have one outer element, eg...

This code snippet will work okay because there is a <div> as the outer element and then all the other elements are anclosed inside it.

const paragraphs = (
   <div id="i-am-the-outermost-element">
      <p>I am a paragraph.</p>
      <p>I, too, am a paragraph.</p>
   </div>
);


Whereas this code snippet will NOT work as the elements (<p>) are not enclosed inside another element.

const paragraphs = (
   <p>I am a paragraph.</p>
   <p>I, too, am a paragraph.</p>
);


Top

Rendering JSX

To render a JSX expression means to make it appear onscreen.

The following code would render a JSX expression...
ReactDOM.render(
   <h1>Hello World</h1>,    document.getElementById('app')


It assumes you already have an empty element in your html file with an ID equal to 'app', eg
<div id="app"></div>

Passing a Variable to ReactDOM.render()

You can also set all your elements up in a variable and then pass the variable to ReactDOM.render(), eg...

const toDoList = (
   <ol>
      <li>Learn React</li>
      <li>Become a Developer</li>
   </ol>
);

ReactDOM.render(
   toDoList,
   document.getElementById('app')
);


Top

Self Closing Tags

When you write a self-closing tag in HTML, it is optional to include a forward-slash immediately before the final angle-bracket, eg...

<br /> and <br>

Are both accepted in HTML (although it's good practice to use the /)
BUT in JSX you must include the slash (/) otherwise it will error.

Curly Braces

Any code in between the tags of a JSX element will be read as JSX, not as regular JavaScript!
JSX doesn’t add numbers - it reads them as text, just like HTML.

Which is usually okay, eg...
<h1>2 + 3</h1>
displays as a normal HTML <h1> header
and displays itself as 2 + 3

BUT if, for some reason, you wanted it to process as a JavaScript command then you must enclose it in curly braces {}, eg...

<h1>{2 + 3)</h1>
then it will display as 5

<h1>2 + 3 = {2 + 3)</h1>
then it will display as 2 + 3 = 5

Top

Curly Braces Part 2

When you inject JavaScript into JSX, that JavaScript is part of the same environment as the rest of the JavaScript in your file.

That means that you can access variables while inside of a JSX expression, even if those variables were declared on the outside, eg...

const name = "Gary";

ReactDOM.render(
   <h1>My name is {name}</h1> ,
   document.getElementById('app')
);

displays as a <h1> header
and displays itself as My name is Gary



NOTE...

When creating variables the following applies:-

Using parenthesis () basically means you are creating a variable that holds a JSX value.
const myVar = (<h1>H1 text here</h1>;

and using curly braces {} basically means that you are creating a variable that holds properties.
const myVar = {
   prop1: "Property 1",
   prop2: "Property 2"
};

myVar.prop1 will = "Property 1"
and myVar.prop2 will = "Property 2"


Curly Braces Part 3

A more common way of doing things can be, for example...

const myElement = document.getElementById("app");
const imgSize = "200px";

const panda = (
   <img
      src="images/panda.jpg"
      alt="Panda Pic"
      height={imgSize}
      width={imgSize}
   />
);

ReactDOM.render(panda, myElement);



Or even this...

const myElement = document.getElementById("app");
const imgSize = "200px";

const pics = {
   panda: "images/panda.jpg",
   owl: "images/owl.jpg",
   tiger: "images/tiger.jpg"
} ;

const panda = (
   <img
      src={pics.panda}
      alt="Panda Pic"
      height={imgSize}
      width={imgSize}
   />
);

const owl = (
   <img
      src={pics.owl}
      alt="Owl Pic"
      height={imgSize}
      width={imgSize}
   />
);

ReactDOM.render(panda, myElement);
or
ReactDOM.render(owl, myElement);


Which may be a good way of storing the names of image files to use on the page.

ALSO see the pane (at the bottom) for more info on creating a function/variable for myElement.
Or Click Here to go straight there.

Top

Event Listeners in JSX

JSX elements can have event listeners, just like HTML elements can.
Programming in React means constantly working with event listeners.

You create an event listener by giving a JSX element a special attribute, eg...


This adds the onClick event to the image
and the value of myFunc will be passed to it (which is a function).


An event listener attribute’s name should be something like onClick or onMouseOver: the word on, plus the type of event that you’re listening for.

You can see a list of valid event names Here.

Alternatively, see w3schools document on it Here.

Just like HTML, React can perform actions based on user events. React has the same events as HTML: click, change, mouseover etc.

React events are written in camelCase syntax:
onClick instead of onclick.
React event handlers are written inside curly braces:
onClick={shoot} instead of onClick="shoot()"

Event Listener Code Example

The below is an example of the code from a .js file

import React from 'react';
import ReactDOM from 'react-dom';

function makeDoggy(e) {
  // When called, this function changes the 
  // picture to be
  // that of a doggy.
  e.target.setAttribute('src', 
    'https://content.codecademy.com/courses/
        React/react_photo-puppy.jpeg');

  e.target.setAttribute('alt', 'doggy');
}

const kitty = (
   <img 
      onClick={makeDoggy} 
      src="https://content.codecademy.com/
        courses/React/react_photo-kitty.jpg" 
      alt="kitty" />
);

ReactDOM.render(kitty, document.getElementById('app'));

When run it displays a picture of a cat.
When you click on the picture it activates the 'onClick' event and runs the makeDoggy function
which changes it to a picture of a dog.

Note...
The function makeDoggy requires one parameter (called e) and this gets automatically passed via the onClick call on the <img /> element (so it is not specified in the code of the <img />)

Top

JSX Conditionals...

'if' statements that don't work

Here’s a rule that you need to know:
you can not inject an 'if' statement into a JSX expression.

For Example...this will not work...
const myJSX = (
   <p>
      {
         if (purchase.complete) {
            "Thank you for your order!"
         }
      }
   </p>
);


JSX Conditionals Part 2...

'if' statements that DO WORK

How can you write a conditional, if you can’t inject an if statement into JSX?

One option is to write an if statement, and NOT inject it into JSX.

For Example...

let message;

if (user.age >= drinkingAge) {
    message = (
      <h1>
         Buy Drink
      </h1>
   );

} else {
    message = (
      <h1>
         Do Not Buy Drink
      </h1>
   );

}

ReactDOM.render(
   message,
   document.getElementById('app')
);


So the code in red relates to the JSX code
The rest of the code will get run but is outside of the JSX code.
This way the message will be relevant to what you need it to be.

Top

JSX Conditionals: The Ternary Operator

The ternary operator works the same way in React as it does in regular JavaScript.

A little reminder...
x ? y : z
Where x is 'true' or 'false' (truthy or falsy).
So if x is 'truthy' then use y
but if x is 'falsey' then use z


eg...

const headline = (
   <h1>
      { age >= drinkingAge ? 'Buy Drink' : 'Do Not Buy Drink' }
   </h1>
);


JSX Conditionals: The Ternary Operator (pt 2)

An example of code:-

import React from 'react';
import ReactDOM from 'react-dom';

function coinToss () {
  // Randomly return either 'heads' or 'tails'.
  return Math.random() < 0.5 ? 'heads' : 'tails';
}

const pics = {
  kitty: 'Images/kitty.jpg',
  doggy: 'Images/puppy.jpeg'
};

const img = <img 
    src={pics[coinToss() === 'heads' ? 'kitty' : 'doggy']} 
  />

ReactDOM.render(
	img, 
	document.getElementById('app')
);

This code creates a function called coinToss() which returns either a "heads" or a "tails"

It then creates an object called pics that has two properties (kitty) and doggy.

It then creates a JSX variable called img and the src attribute uses the 'Ternary Operator'.
Which says if coinToss() = "heads" then use the kitty picture otherwise use the doggy picture.

Then render the screen with whichever picture (kitty or doggy) was selected.

NOTE...
When referring to the properties of pics you could say
pics.kitty or pics.doggy
or you could also say
pics["kitty"] or pics["doggy"]

Therefore in the code above we had to use the pics["kitty"] (or pics["doggy"]) version as the Ternary Operator returned a string for "kitty" and "doggy".


Top

JSX Conditionals: && and ||

&& works best in conditionals that will sometimes do an action, but other times do nothing at all.

In other words if the condition is truthy then perform the command
and if it is falsy then do nothing.

For example...

const drinks = (
   <ul>
      <li>Coca Cola</li>
      <li>Lemonade</li>
      { age >= 16 && <li>Cider</li>}
      { age >= 18 && <li>Beer</li>}
      { age >= 21 && <li>Scotch</li>}
      { !(age >= 21) && <li>Water</li>}
   </ul>
);


This would create an un-ordered list that has
Coca Cola
Lemonade

But will Only list Cider if you are over 16
But will Only list Beer if you are over 18
But will Only list Scotch if you are over 21

But will Only list Water if you are NOT over 21
- the ! means NOT, though I could have just said age < 21 but I wanted to show a different way.



|| can be used in this way...

say you have a string (myString) which is empty
var myString = "";

An empty string is treated as FALSEY
So you can say, eg...
{ myString || <li>Show this message</li>}

The result would be it INCLUDES the <li>Show this message</li>


BUT if myString = <li>ABCDEF</li> then it is treated as TRUTHY which means
{ myString || <li>Show this message</li>}

The result would be it INCLUDES the value of myString and will therefore include
<li>ABCDEF</li>

JSX .map

If you want to create a list of JSX elements, then .map() is often your best bet.
It is an array method.

For example...

const strings = ['Home', 'Shop', 'About Me'];

const listItems = strings.map(string => <li>{string}</li>);

ReactDOM.render(
    <ul>{listItems}</ul>,
    document.getElementById('app')
);


What happened with the above code is

const strings = ['Home', 'Shop', 'About Me'];
This line creates an array of 3 items

const listItems = strings.map(string => <li>{string}</li>);
This line uses the strings.map method and creates a new array (called listItems)
each item in the new array will look like

<li>{string}</li>
where {string} is the item from the original array ('Home', 'Shop' & 'About Me')

ReactDOM.render(<ul>{listItems}</ul>, document.getElementById('app'));
This line will then render the un-ordered list and put all the items from the new array (listItems) inside it.

Top

JSX Keys

A key is a JSX attribute.
The attribute’s name is key. The attribute’s value should be something inique, similar to an id attribute.

keys don’t do anything that you can see!
React uses them internally to keep track of lists.
If you don’t use keys when you’re supposed to, React might accidentally scramble your list-items into the wrong order.

Not all lists need to have keys.
A list needs keys if either of the following are true:-

1.
The list-items have memory from one render to the next.
For instance, when a to-do list renders, each item must “remember” whether it was checked off.

2.
A list’s order might be shuffled.
For instance, a list of search results might be shuffled from one render to the next.

If neither of these conditions are true, then you don’t have to worry about keys.
If you aren’t sure then it never hurts to use them!

For Example...

<ul>
   <li key="li-01">Example1</li>
   <li key="li-02">Example2</li>
   <li key="li-03">Example3</li>
</ul>


JSX Keys with .map()

Each key must be a unique string that React can use to correctly pair each rendered element with its corresponding item in the array.

So how can you get .map() to produce unique keys?

Well, first, add an i parameter to .map()‘s inner function, so that you can access each array items unique index:

Example...

const peopleLIs = people.map((person, i) =>
   key={'person_' + i}
);


So when it reads in the array (people) it will read in each item as person and it will give the parameter i the value of the items index number.
Therefore creating a key of
"person_0"
"person_1"
"person_2"
etc...


NOTE
When there is more than 1 parameter they must be inside brackets (), eg...
people.map( (person, i) =>

Top

React.createElement()

You can write React code without JSX but the majority do use it.

When a JSX element is compiled , the compiler transforms the JSX element into the React code for you automatically.

Here is an example of JSX code...

const h1 = <h1>Hello world</h1>

And here is the same thing without JSX...

const h1 = React.createElement("h1", null, "Hello World");

Top

Creating a Function for React.render()

Seeing as I had to keep typing
document.getElementById('app')
continuously in my lessons I figured I would also try to create a function/variable to hold the value for me.

For Example...

I kept typing...

ReactDOM.Render(
   JSXString,
   document.getElementById('app'))
);


So I thought I would, instead, create a variable that runs a function - and do this...

const myElement = id => {
   let myL = document.getElementById(id);
   return myL;
}


then I can call it like this
ReactDOM.render(JSXString, myElement("app"));
or
ReactDOM.render(JSXString, myElement("root"));



I also found that I could just call a function instead of storing the function in a variable...

function myElement(id) {
   let myL = document.getElementById(id);
   return myL;
}


then I can call it like this
ReactDOM.render(JSXString, myElement("app"));
or
ReactDOM.render(JSXString, myElement("root"));


Both ways work well.

Top