;`
This funny tag syntax is neither a string nor HTML.
It is called JSX, and it is a syntax extension to JavaScript. We recommend using it with React to describe what the UI should look like. JSX may remind you of a template language, but it comes with the full power of JavaScript.
JSX produces React “elements”.
Instead of artificially separating technologies by putting markup and logic in separate files, React separates concerns with loosely coupled units called “components” that contain both.
- Embedding Expressions in JSX
In the example below, we declare a variable called name and then use it inside JSX by wrapping it in curly braces:
const name = 'Josh Perez';
const element =
Hello, {name}
;
- JSX is an Expression Too
After compilation, JSX expressions become regular JavaScript function calls and evaluate to JavaScript objects.
This means that you can use JSX inside of if statements and for loops, assign it to variables, accept it as arguments, and return it from functions:
- Specifying Attributes with JSX
You may use quotes to specify string literals as attributes:
`const element = link ;`
You may also use curly braces to embed a JavaScript expression in an attribute:
`const element = ;`
- Specifying Children with JSX
If a tag is empty, you may close it immediately with />, like XML:
`const element = ;`
JSX tags may contain children:
1 2 3 4 5 6
const element = ( <div> <h1>Hello!</h1> <h2>Good to see you here.</h2> </div> );
- JSX Prevents Injection Attacks
It is safe to embed user input in JSX:
const title = response.potentiallyMaliciousInput;
// This is safe:
const element =
{title}
;
By default, React DOM escapes any values embedded in JSX before rendering them. Thus it ensures that you can never inject anything that’s not explicitly written in your application. Everything is converted to a string before being rendered. This helps prevent XSS (cross-site-scripting) attacks.
- Which characters need to be escaped in HTML
inserting text content in your document in a location where text content is expected
By "a location where text content is expected", I mean inside of an element or quoted attribute value where normal parsing rules apply. For example:
HERE
or
...
.
Inside of an element, this just includes the entity escape ampersand & and the element delimiter less-than and greater-than signs < >:
& becomes &
< becomes <
> becomes >
Inside of attribute values you must also escape the quote character you're using:
" becomes "
' becomes '
I encourage you to escape all five in all cases to reduce the chance of making a mistake.
In general, you should not escape spaces as . is not a normal space, it's a non-breaking space. You can use these instead of normal spaces to prevent a line break from being inserted between two words, or to insert extra space without it being automatically collapsed, but this is usually a rare case. Don't do this unless you have a design constraint that requires it.
- !
content that has special parsing rules or meaning, such as inside of a script or style tag, or as an element or attribute name. For example: `..., , , or
...
.`
In these contexts, the rules are more complicated and it's much easier to introduce a security vulnerability. I strongly discourage you from ever inserting dynamic content in any of these locations.
There's usually a safer alternative, such as putting the dynamic value in an attribute and then handling it with JavaScript.
- JSX Represents Objects
Babel compiles JSX down to React.createElement() calls.
These two examples are identical:
const element = ( <h1className="greeting"> Hello, world! </h1> ); const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!' ); React.createElement() performs a few checks to help you write bug-free code but essentially it creates an object like this:
// Note: this structure is simplified const element = { type: 'h1', props: { className: 'greeting', children: 'Hello, world!' } };
These objects are called “React elements”. You can think of them as descriptions of what you want to see on the screen.
### Rendering an Element into the DOM
Let’s say there is a
somewhere in your HTML file:
``
We call this a “root” DOM node because everything inside it will be managed by React DOM.
Applications built with just React usually have a single root DOM node. If you are integrating React into an existing app, you may have as many isolated root DOM nodes as you like.
To render a React element, first pass the DOM element to ReactDOM.createRoot(), then pass the React element to root.render():
### Function and Class Components
The simplest way to define a component is to write a JavaScript function:
function Welcome(props) {
return
Hello, {props.name}
;
}
This function is a valid React component because it accepts a single “props” (which stands for properties) object argument with data and returns a React element. We call such components “function components” because they are literally JavaScript functions.
You can also use an ES6 class to define a component:
The above two components are equivalent from React’s point of view.
- Composing Components
Components can refer to other components in their output. This lets us use the same component abstraction for any level of detail. A button, a form, a dialog, a screen: in React apps, all those are commonly expressed as components.
For example, we can create an App component that renders Welcome many times:
It accepts author (an object), text (a string), and date (a date) as props, and describes a comment on a social media website.
This component can be tricky to change because of all the nesting, and it is also hard to reuse individual parts of it. Let’s extract a few components from it.
First, we will extract Avatar:
The Avatar doesn’t need to know that it is being rendered inside a Comment. This is why we have given its prop a more generic name: user rather than author.
We recommend naming props from the component’s own point of view rather than the context in which it is being used.
We can now simplify Comment a tiny bit:
- Adding Lifecycle Methods to a Class
We want to set up a timer whenever the Clock is rendered to the DOM for the first time. This is called “mounting” in React.
We also want to clear that timer whenever the DOM produced by the Clock is removed. This is called “unmounting” in React.
1. When the Clock output is inserted in the DOM, React calls the componentDidMount() lifecycle method. Inside it, the Clock component asks the browser to set up a timer to call the component’s tick() method once a second.
2. Every second the browser calls the tick() method. Inside it, the Clock component schedules a UI update by calling setState() with an object containing the current time.
3. Thanks to the setState() call, React knows the state has changed, and calls the render() method again to learn what should be on the screen. This time, this.state.date in the render() method will be different, and so the render output will include the updated time. React updates the DOM accordingly.
4. If the Clock component is ever removed from the DOM, React calls the componentWillUnmount() lifecycle method so the timer is stopped.
- State Updates May Be Asynchronous
React may batch multiple setState() calls into a single update for performance.
Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.
For example, this code may fail to update the counter:
// Wrong
To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
// Correct
### Handling Events
Handling events with React elements is very similar to handling events on DOM elements. There are some syntax differences:
React events are named using camelCase, rather than lowercase.
With JSX you pass a function as the event handler, rather than a string.
- this
You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.
render() { // This syntax ensures `this` is bound within handleClick return ( <buttononClick={() => this.handleClick()}> Click me </button> ); } }
The problem with this syntax is that a different callback is created each time the LoggingButton renders. In most cases, this is fine. However, if this callback is passed as a prop to lower components, those components might do an extra re-rendering. We generally recommend binding in the constructor or using the class fields syntax, to avoid this sort of performance problem.
- Passing Arguments to Event Handlers
Inside a loop, it is common to want to pass an extra parameter to an event handler. For example, if id is the row ID, either of the following would work:
``
``
The above two lines are equivalent, and use arrow functions and Function.prototype.bind respectively.
In both cases, the e argument representing the React event will be passed as a second argument after the ID. With an arrow function, we have to pass it explicitly, but with bind any further arguments are automatically forwarded.
- While declaring a variable and using an if statement is a fine way to conditionally render a component, sometimes you might want to use a shorter syntax
- Inline If with Logical && Operator
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.
Note that returning a falsy expression will still cause the element after && to be skipped but will return the falsy expression. In the example below,
- Inline If-Else with Conditional Operator
Another method for conditionally rendering elements inline is to use the JavaScript conditional operator condition ? true : false.
Preventing Component from Rendering
In rare cases you might want a component to hide itself even though it was rendered by another component. To do this return null instead of its render output.
1 2 3 4 5 6 7 8 9 10 11
functionWarningBanner(props) { if (!props.warn) { returnnull; }
- Rendering Multiple Components
You can build collections of elements and include them in JSX using curly braces {}.
Below, we loop through the numbers array using the JavaScript map() function. We return a
element for each item. Finally, we assign the resulting array of elements to listItems:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
{number}
);
Then, we can include the entire listItems array inside a
element:
When you run code, you’ll be given a warning that a key should be provided for list items. A “key” is a special string attribute you need to include when creating lists of elements.
- Keys
Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity:
We don’t recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state.
Example: Incorrect Key Usage
functionListItem(props) { const value = props.value; return ( // Wrong! There is no need to specify the key here: <likey={value.toString()}> {value} </li> ); }
functionNumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => // Wrong! The key should have been specified here: <ListItemvalue={number} /> ); return ( <ul> {listItems} </ul> ); }
Example: Correct Key Usage
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
functionListItem(props) { // Correct! There is no need to specify the key here: return<li>{props.value}</li>; }
functionNumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => // Correct! Key should be specified inside the array. <ListItemkey={number.toString()}value={number} /> ); return ( <ul> {listItems} </ul> ); }
- Embedding map() in JSX
JSX allows embedding any expression in curly braces so we could inline the map() result:
- Composition vs Inheritance
React has a powerful composition model, and we recommend using composition instead of inheritance to reuse code between components.
- Containment
Some components don’t know their children ahead of time. This is especially common for components like Sidebar or Dialog that represent generic “boxes”.
We recommend that such components use the special children prop to pass children elements directly into their output:
This lets other components pass arbitrary children to them by nesting the JSX:
1 2 3 4 5 6 7 8 9 10 11 12
functionWelcomeDialog() { return ( <FancyBordercolor="blue"> <h1className="Dialog-title"> Welcome </h1> <pclassName="Dialog-message"> Thank you for visiting our spacecraft! </p> </FancyBorder> ); }
Try it on CodePen
Anything inside the JSX tag gets passed into the FancyBorder component as a children prop. Since FancyBorder renders {props.children} inside a
, the passed elements appear in the final output.
- sometimes you might need multiple “holes” in a component. In such cases you may come up with your own convention instead of using children:
Try it on CodePen
React elements like and are just objects, so you can pass them as props like any other data. This approach may remind you of “slots” in other libraries but there are no limitations on what you can pass as props in React.
- Specialization
Sometimes we think about components as being “special cases” of other components. For example, we might say that a WelcomeDialog is a special case of Dialog.