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.
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' />
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>
);
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>
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')
);
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.
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
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
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);
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()"
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'));
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>
);
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.
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>
);
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') );
&& 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.
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.
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>
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) =>
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");
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"));