This page is specific to React. For a more general guide, see the JSX general page. Including various ways to process JSX.

Creating elements or components (which are made of elements) using JSX syntax.

Function vs variable

Function

  • JSX:
      function Greet() {
        return <h1>Hello, World!</h1>
      }
    

With parameters:

  • JSX:
      function Greet(props) {
        const { name } = props;
          
        return <h1>Hello, { name }!</h1>
      }
    

Variable

const el = h1>Hello, World!</h1>
const name = 'World'
const greet = h1>Hello, {name}!</h1>

Structuring JSX

Using approaches like outer elements or not for writing JSX.

Single element

This is a simple case. Just return a single flat element.

  • JSX:
      function Greet() {
        return <h1>Hello, World!</h1>
      }
    
  • HTML DOM result:
      <div id="root">
          <h1>Hello, World!</h1>
      </div>
    
  • Compiled JS:
      function Greet() {
        return React.createElement("h1", null, "Hello, World!");
      }
    

Group elements without a parent element

Here we use an empty JSX fragment to group our elements together, but it won’t get rendered.

  • JSX:
      return <>
          <h1>Hello, World!</h1>
          <h2>This is React</h2>
        </>
    

    Add brackets if you want to start the tag on its own line after return.

      function Greet() {
        return (
          <>
            <h1>Hello, World!</h1>
            <h2>This is React</h2>
          </>
        )
      }
    
  • HTML DOM result:
      <div id="root">
          <h1>Hello, World!</h1>
          <h2>This is React</h2>
      </div>
    
  • Compiled JS:
      function Greet() {
        return React.createElement(React.Fragment, null,
          React.createElement("h1", null, "Hello, World!"),
          React.createElement("h2", null, "This is React"));
        }
    

Be careful of this. Without brackets, this would return undefined.

  • JSX:
      function Greet() {
        return
          <>
            <h1>Hello, World!</h1>
            <h2>This is React</h2>
          </>
      }
    

Group elements under a parent element

Add a parent element. Such as a div, with a class if you like.

You can optionally use the brackets. It doesn’t change the result but allows you to start your opening tag on a new line. Note there are no commas between elements.

  • JSX:
      function Greeting() {
        return <div className="my-class">
            <h1>Hello, World!</h1>
            <h2>This is React</h2>
          </div>
      }
    

    With brackets:

      function Greeting() {
        return (
          <div className="my-class">
            <h1>Hello, World!</h1>
            <h2>This is React</h2>
          </div>
        )
    
  • HTML DOM result:
      <div id="root">
          <div class="my-class">
              <h1>Hello, World!</h1>
              <h2>This is React</h2>
          </div>
      </div>
    
  • Compiled JS equivalent:
      function Greeting() {
        return React.createElement(
          "div",
          { className="my-class" },
          React.createElement("h1", null, "Hello, World!"),
          React.createElement("h2", null, "This is React");
          );
      }
    

JS expressions in JSX

Use { EXPRESSION }.

Substituting variables.

function Greet(props) {
 const { name, age } = props

  const status = age >= 18 ? 'major' : 'minor'

  return (
    <>
      <h1>Hello, { name }</h1>
      <p>{ status }</p>
    </>
  )
}

You can put an expression in like an arrow function call or ternary.

function Greet(props) {
  const { age } = props

  return (
    <>
      <h1>Hello</h1>
      <p>{age >= 18 ? 'major' : 'minor'}</p>
    </>
  )
}

If your JSX gets long and complicated, consider rather making a variable first and then inserting that.

Setting attributes.

function Image(props) {
  const { path } = props

  return <img src={ path } />
}

Setting a function as an event:

function Greet() {
  return (
    <button onClick={() => alert("Hello!")}>
      Greet
    </button>
  );
}
import { setState } from "react";

function LikeButton() {
  return (
    <button onClick={() => setState({ liked: true })}>
      Like
    </button>
  );
}

Or this.setState - possibly only for class components?

Here using an intermediate function. Useful for multiple lines that would not good look is JSX.

Usestate is unpacked as a value and a function to set, using your own names.

import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>

      const increment = () => setCount(count + 1)

      <button onClick={increment}>Click me</button>
    </div>
  );
}

CSS

Put a key-value pair object inside your JS expression.

i.e. {{ MY_CSS }}.

e.g.

function Greet() {
  return <h1 style={{ color: 'red' }}>
    Hello, World!
  </h1>
}

Custom components

Insert a component as a element in JSX.

The first component here doesn’t take any properties.

The second one takes a name property, which can be passed as a literal value or as a JS expression such as a variable.

function Greet() {
  return <p>Hello</p>
}

function GreetPerson(props) {
  return <p>Hello, {props.name}!</p>
}

function App() {
  const name = "Joe"

  return (
    <div className="App">
      <Greet/>
      <GreetPerson name="World"/>
      <GreetPerson name={name}/>
    </div>
  )
}

With and without JSX

Example from React docs

Writing code with JSX.

function LikeButton() {
  return (
    <button onClick={() => this.setState({ liked: true })}>
      Like
    </button>
  );
}

Writing code without JSX - it is more verbose and less like HTML. Create an element using the createElement function. Here it is aliased to e.

const e = React.createElement;

function LikeButton() {
  return e(
    'button',
    { onClick: () => this.setState({ liked: true }) },
    'Like'
  );
}

Compiled JSX

See the Babel REPL to get live conversion of your JSX to plain JS.

For example:

  • Input
      const element = <h1>Hello, world!</h1>;
      const container = document.getElementById('root');
        
      ReactDOM.render(element, container);
    
  • Result
      const element = /*#__PURE__*/React.createElement("h1", null, "Hello, world!");
      const container = document.getElementById('root');
        
      ReactDOM.render(element, container);
    

Allow JSX syntax in TypeScript

From IntrinsicElements in JSX docs of TS.

You can try as .d.ts to match shims-vue.d.ts, but Deno + TypeScript gave a me warning that it could not import so I had to use .ts instead.

Catch-all

  • src/shims-react.ts
      declare namespace JSX {
        interface IntrinsicElements {
          [elemName: string]: any;
        }
      }
    

Verbose

  • src/shims-react.ts
      declare namespace JSX {
        interface IntrinsicElements {
          h1: any;
          h2: any;
          div: any;
          p: any;
          // ...
        }
      }