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.

252 lines
6.8 KiB

---
id: jsx-in-depth
title: JSX in Depth
permalink: jsx-in-depth.html
prev: displaying-data.html
next: jsx-gotchas.html
---
JSX is a JavaScript XML syntax transform recommended for use
with React.
> Note:
>
> Don't forget the `/** @jsx React.DOM */` pragma at the beginning of your file! This tells JSX to process the file for React.
>
> If you don't include the pragma, your source will remain untouched, so it's safe to run the JSX transformer on all JS files in your codebase if you want to.
## Why JSX?
React works out of the box without JSX. Simply construct your markup using the
functions on `React.DOM`. For example, here's how to construct a simple link:
```javascript
var link = React.DOM.a({href: 'http://facebook.github.io/react'}, 'React');
```
We recommend using JSX for many reasons:
* It's easier to visualize the structure of the DOM.
* Designers are more comfortable making changes.
* It's familiar for those who have used MXML or XAML.
## The Transform
JSX transforms from an XML-like syntax into native JavaScript. XML elements and
attributes are transformed into function calls and objects, respectively.
```javascript
var Nav;
// Input (JSX):
var app = <Nav color="blue" />;
// Output (JS):
var app = 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 = Nav({color:"blue"}, Profile(null, "click"));
```
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:
>
> Details about the code transform are given here to increase understanding, but
> your code should not rely on these implementation details.
## React and JSX
React and JSX are independent technologies, but JSX was primarily built with
React in mind. The two valid uses of JSX are:
* To construct instances of React DOM components (`React.DOM.*`).
* To construct instances of composite components created with
`React.createClass()`.
### React DOM Components
To construct a `<div>` is to create a variable that refers to `React.DOM.div`.
```javascript
var div = React.DOM.div;
var app = <div className="appClass">Hello, React!</div>;
```
11 years ago
### React Composite Components
To construct an instance of a composite component, create a variable that
references the class.
```javascript
var MyComponent = React.createClass({/*...*/});
var app = <MyComponent someProperty={true} />;
```
JSX will infer the component's name from the variable assignment and specify
the class's [displayName](/react/docs/component-specs.html#displayName) accordingly.
See [Multiple Components](/react/docs/multiple-components.html) to learn more about using composite components.
> Note:
>
> Since JSX is JavaScript, identifiers such as `class` and `for` are discouraged
> as XML attribute names. Instead, React DOM components expect attributes like
> `className` and `htmlFor`, respectively.
## DOM Convenience
Having to define variables for every type of DOM element can get tedious
(e.g. `var div, span, h1, h2, ...`). JSX provides a convenience to address this
problem by allowing you to specify a variable in an `@jsx` docblock field. JSX
will use that field to find DOM components.
```javascript
/**
* @jsx React.DOM
*/
var Nav;
// Input (JSX):
var tree = <Nav><span /></Nav>;
// Output (JS):
var tree = Nav(null, React.DOM.span(null));
```
> Remember:
>
> JSX simply transforms elements into function calls and has no notion of the
> DOM. The docblock parameter is only a convenience to resolve the most commonly
> used elements. In general, JSX has no notion of the DOM.
## Namespaced Components
If you are building a component that have a lot of childrens, or if you are building your application with some categories of reusable components (like a `Form` category), to make more simple and easiest, you can use a *namespaced component* to avoid something like this:
```javascript
var Form = MyFormComponent;
var FormRow = Form.Row;
var FormLabel = Form.Label;
var FormInput = Form.Input;
var App = (
<Form>
<FormRow>
<FormLabel />
<FormInput />
</FormRow>
</Form>
);
```
Instead of declare a bunch of variables at the top, you'll get just one component that have other components as attributes.
```javascript
var Form = MyFormComponent;
var App = (
<Form>
<Form.Row>
<Form.Label />
<Form.Input />
</Form.Row>
</Form>
);
```
For doing 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 take care to make the things right when compile your code.
```javascript
var App = (
Form(null,
Form.Row(null,
Form.Label(null),
Form.Input(null)
)
)
);
```
> Note:
>
> This feature is available in [v0.11](http://facebook.github.io/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 = Person({name: window.isLoggedIn ? window.name : ''});
```
### 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 = Container(null, window.isLoggedIn ? Nav(null) : Login(null));
```
### 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>
);
```
## Prior Work
JSX is similar to several other JavaScript embedded XML language
proposals/projects. Some of the features of JSX that distinguish it from similar
efforts include:
* JSX is a simple syntactic transform.
* JSX neither provides nor requires a runtime library.
* JSX does not alter or add to the semantics of JavaScript.
JSX is similar to HTML, but not exactly the same. See [JSX gotchas](/react/docs/jsx-gotchas.html) for some key differences.