You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
6.4 KiB

---
id: jsx-in-depth
title: JSX in Depth
permalink: jsx-in-depth.html
prev: displaying-data.html
next: jsx-spread.html
---
[JSX](https://facebook.github.io/jsx/) is a JavaScript syntax extension that looks similar to XML. You can use a simple JSX syntactic transform with React.
## Why JSX?
You don't have to use JSX with React. You can just use plain JS. However, we recommend using JSX because it is a concise and familiar syntax for defining tree structures with attributes.
It's more familiar for casual developers such as designers.
XML has the benefit of balanced opening and closing tags. This helps make large trees easier to read than function calls or object literals.
It doesn't alter the semantics of JavaScript.
## HTML Tags vs. React Components
React can either render HTML tags (strings) or React components (classes).
To render a HTML tag, just use lower-case tag names in JSX:
```javascript
var myDivElement = <div className="foo" />;
React.render(myDivElement, document.getElementById('example'));
```
To render a React Component, just create a local variable that starts with an upper-case letter:
```javascript
var MyComponent = React.createClass({/*...*/});
var myElement = <MyComponent someProperty={true} />;
React.render(myElement, document.getElementById('example'));
```
React's JSX uses the upper vs. lower case convention to distinguish between local component classes and HTML tags.
> Note:
>
> Since JSX is JavaScript, identifiers such as `class` and `for` are discouraged
> as XML attribute names. Instead, React DOM components expect DOM property
> names like `className` and `htmlFor`, respectively.
## The Transform
React JSX transforms from an XML-like syntax into native JavaScript. XML elements, attributes and children are transformed into arguments that are passed to `React.createElement`.
```javascript
var Nav;
// Input (JSX):
var app = <Nav color="blue" />;
// Output (JS):
var app = React.createElement(Nav, {color:"blue"});
```
Notice that in order to use `<Nav />`, the `Nav` variable must be in scope.
JSX also allows specifying children using XML syntax:
```javascript
var Nav, Profile;
// Input (JSX):
var app = <Nav color="blue"><Profile>click</Profile></Nav>;
// Output (JS):
var app = React.createElement(
Nav,
{color:"blue"},
React.createElement(Profile, null, "click")
);
```
JSX will infer the class's [displayName](/react/docs/component-specs.html#displayname) from the variable assignment when the displayName is undefined:
```javascript
// Input (JSX):
var Nav = React.createClass({ });
// Output (JS):
var Nav = React.createClass({displayName: "Nav", });
```
Use the [JSX Compiler](/react/jsx-compiler.html) to try out JSX and see how it
desugars into native JavaScript, and the
[HTML to JSX converter](/react/html-jsx.html) to convert your existing HTML to
JSX.
If you want to use JSX, the [Getting Started](/react/docs/getting-started.html) guide shows how to setup compilation.
> Note:
>
> The JSX expression always evaluates to a ReactElement. The actual
> implementation details may vary. An optimized mode could inline the
> ReactElement as an object literal to bypass the validation code in
> `React.createElement`.
## Namespaced Components
If you are building a component that has many children, like a form, you might end up with something with a lot of variable declarations:
```javascript
// Awkward block of variable declarations
var Form = MyFormComponent;
var FormRow = Form.Row;
var FormLabel = Form.Label;
var FormInput = Form.Input;
var App = (
<Form>
<FormRow>
<FormLabel />
<FormInput />
</FormRow>
</Form>
);
```
To make it simpler and easier, *namespaced components* let you use one component that has other components as attributes:
```javascript
var Form = MyFormComponent;
var App = (
<Form>
<Form.Row>
<Form.Label />
<Form.Input />
</Form.Row>
</Form>
);
```
To do this, you just need to create your *"sub-components"* as attributes of the main component:
```javascript
var MyFormComponent = React.createClass({ ... });
MyFormComponent.Row = React.createClass({ ... });
MyFormComponent.Label = React.createClass({ ... });
MyFormComponent.Input = React.createClass({ ... });
```
JSX will handle this properly when compiling your code.
```javascript
var App = (
React.createElement(Form, null,
React.createElement(Form.Row, null,
React.createElement(Form.Label, null),
React.createElement(Form.Input, null)
)
)
);
```
> Note:
>
> This feature is available in [v0.11](/react/blog/2014/07/17/react-v0.11.html#jsx) and above.
## JavaScript Expressions
### Attribute Expressions
To use a JavaScript expression as an attribute value, wrap the expression in a
pair of curly braces (`{}`) instead of quotes (`""`).
```javascript
// Input (JSX):
var person = <Person name={window.isLoggedIn ? window.name : ''} />;
// Output (JS):
var person = React.createElement(
Person,
{name: window.isLoggedIn ? window.name : ''}
);
```
### Boolean Attributes
Omitting the value of an attribute causes JSX to treat it as `true`. To pass `false` an attribute expression must be used. This often comes up when using HTML form elements, with attributes like `disabled`, `required`, `checked` and `readOnly`.
```javascript
// These two are equivalent in JSX for disabling a button
<input type="button" disabled />;
<input type="button" disabled={true} />;
// And these two are equivalent in JSX for not disabling a button
<input type="button" />;
<input type="button" disabled={false} />;
```
### Child Expressions
Likewise, JavaScript expressions may be used to express children:
```javascript
// Input (JSX):
var content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>;
// Output (JS):
var content = React.createElement(
Container,
null,
window.isLoggedIn ? React.createElement(Nav) : React.createElement(Login)
);
```
### Comments
It's easy to add comments within your JSX; they're just JS expressions. You just need to be careful to put `{}` around the comments when you are within the children section of a tag.
```javascript
var content = (
<Nav>
{/* child comment, put {} around */}
<Person
/* multi
line
comment */
name={window.isLoggedIn ? window.name : ''} // end of line comment
/>
</Nav>
);
```
> NOTE:
>
> JSX is similar to HTML, but not exactly the same. See [JSX gotchas](/react/docs/jsx-gotchas.html) for some key differences.