Menu

O que é JSX? Regras de sintaxe do JSX no React

JSX é uma extensão de sintaxe do JavaScript que permite escrever marcação parecida com HTML dentro de componentes React. Aprenda as regras: um único elemento raiz, tags fechadas, className, atributos em camelCase, chaves, estilos inline, comentários e no que ele é compilado.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

JSX é uma extensão de sintaxe do JavaScript que permite escrever marcação parecida com HTML dentro do seu código. Componentes React retornam JSX para descrever o que deve aparecer na tela, e uma ferramenta de build o compila em chamadas de função JavaScript comuns. Ele se parece com HTML, mas algumas regras são diferentes, e as chaves permitem colocar qualquer valor JavaScript na marcação.

Tudo dentro de {} é JavaScript: uma propriedade, uma chamada de método, até um map transformando um array em itens de lista. Adicione 'design' ao array skills e tanto a contagem quanto a lista são atualizadas.

Regras do JSX

Retorne um único elemento raiz

Um componente retorna um único valor, então o JSX dele precisa de um único pai. Dois irmãos no nível superior são um erro de sintaxe. Quando você não quer uma <div> extra na página, envolva-os em um fragment, <>...</>:

// Error: Adjacent JSX elements must be wrapped in an enclosing tag
return (
    <h1>Title</h1>
    <p>Text</p>
);

// OK: a fragment groups them without adding a DOM element
return (
    <>
        <h1>Title</h1>
        <p>Text</p>
    </>
);

Quando você precisa de uma key no grupo, use a forma longa <Fragment key={id}>; veja fragments.

Feche todas as tags

O HTML permite deixar algumas tags abertas. O JSX não. Elementos sem filhos se fecham sozinhos com />: <img />, <br />, <input /> e seus próprios componentes, como <Avatar />.

Use className, htmlFor e atributos em camelCase

Os atributos do JSX viram chaves de um objeto JavaScript, então seguem a nomenclatura do JavaScript. class e for são palavras reservadas em JavaScript, e é por isso que o JSX usa className e htmlFor. Atributos de várias palavras e todos os event handlers são camelCase: tabIndex, maxLength, autoFocus, onClick, onChange. Duas exceções mantêm os hifens: os atributos aria-* e data-* são escritos exatamente como no HTML.

Troque className="field" por class="field". O label mantém o estilo, porque o React define o atributo de qualquer jeito, mas um build de desenvolvimento registra "Invalid DOM property class. Did you mean className?" A prévia roda como um build de produção, então você não vai ver esse aviso aqui; use className. Um atributo de string usa aspas (type="email"); qualquer outro valor usa chaves (maxLength={40}, disabled={false}).

Chaves aceitam expressões, não instruções

Dentro de {} você pode escrever qualquer coisa que produza um valor: uma variável, uma conta, uma chamada de função, um ternário, &&, uma template literal. Instruções como if, for e const não produzem valor, então não podem ir ali. Faça o trabalho antes do return ou use uma forma de expressão:

Olhe com atenção antes de clicar: a página mostra um 0 perdido. count && <p>...</p> resulta em 0 quando a contagem é zero, e o React renderiza números, até o zero. Troque por count > 0 && <p>You have mail.</p> e o 0 some. false, null, undefined e true não renderizam nada, e é por isso que um booleano à esquerda do && é seguro. A página sobre renderização condicional trata desses padrões.

Estilos inline usam um objeto

O atributo style recebe um objeto JavaScript, não uma string CSS. Daí vem a aparência de "chaves duplas": o par de fora quer dizer "aqui é JavaScript", o par de dentro é o literal de objeto. Os nomes das propriedades são camelCase (backgroundColor, fontSize), e um número puro significa pixels na maioria das propriedades de tamanho.

Como o estilo é um objeto, ele pode ser calculado a partir do estado como qualquer outro valor. Experimente trocar fontSize: big ? 24 : 16 por fontSize: big ? '2em' : '1em': strings são repassadas com a unidade.

Comentários

Um comentário dentro do JSX vai entre chaves: {/* isto é um comentário */}. Comentários HTML (<!-- -->) são erro de sintaxe. Fora da marcação, no corpo da função, os comentários // comuns funcionam normalmente.

return (
    <div>
        {/* The header is hidden on small screens */}
        <Header />
    </div>
);

Convertendo HTML em JSX

Colar HTML em um componente é um primeiro passo comum, e a maior parte funciona. Estas são as mudanças que você normalmente precisa fazer:

  • class vira className, e for vira htmlFor.
  • Tags vazias se fecham sozinhas: <br> vira <br />, <img src="a.png"> vira <img src="a.png" />.
  • style="color: red; font-size: 14px" vira style={{ color: 'red', fontSize: 14 }}.
  • Atributos de evento recebem uma função, não uma string: onclick="save()" vira onClick={save}.
  • Nomes de atributos viram camelCase: tabindex vira tabIndex, e o stroke-width do SVG vira strokeWidth.
  • <!-- comments --> vira {/* comments */}.
  • Vários elementos no nível superior precisam de um único pai ou de um fragment.

Conversores online de HTML para JSX fazem esses passos por você, mas conhecê-los torna as mensagens de erro fáceis de entender quando você esquece algum.

No que o JSX é compilado

Os navegadores não conseguem executar JSX. Um compilador (como Babel, SWC ou Oxc, que o Vite e os frameworks rodam por você) transforma cada tag em uma chamada de função de react/jsx-runtime:

// What you write
const element = <h1 className="title">Hello, {name}</h1>;
const button = <Button size="small">OK</Button>;
// What the compiler produces (roughly)
import { jsx as _jsx, jsxs as _jsxs } from 'react/jsx-runtime';

const element = _jsxs('h1', { className: 'title', children: ['Hello, ', name] });
const button = _jsx(Button, { size: 'small', children: 'OK' });

Uma tag em minúsculas vira uma string ('h1', um elemento HTML), uma com inicial maiúscula vira uma referência à sua função (Button), os atributos viram o objeto de props, e o conteúdo vira children. Configurações antigas compilavam para React.createElement(type, props, ...children), e é por isso que arquivos antigos começam com import React from 'react' mesmo quando nunca mencionam React. A chamada retorna um objeto comum chamado elemento React. Você pode registrar um no console:

O console mostra que heading é só um dado: um tipo 'h3' e um objeto de props. É também por isso que o JSX pode ser guardado em variáveis, passado para funções e retornado por elas.

O JSX escapa o texto para você

Qualquer string que você coloca entre chaves é renderizada como texto, nunca como HTML. Se um usuário digita <img src=x onerror=alert(1)> em uma caixa de comentário, o React mostra esses caracteres na tela em vez de criar uma tag de imagem. Isso bloqueia por padrão a forma mais comum de cross-site scripting (XSS).

O primeiro parágrafo imprime as tags como caracteres comuns. O segundo usa dangerouslySetInnerHTML, que pula o escape e insere a string como HTML de verdade, então "our own" aparece em negrito. O nome comprido é um aviso: só passe HTML que você mesmo produziu ou que limpou com um sanitizador como o DOMPurify. Passar entrada do usuário ali reabre a brecha de XSS que o JSX fechou.

Perguntas frequentes

O que significa JSX?

JSX significa JavaScript XML. É uma extensão de sintaxe que permite escrever, dentro de código JavaScript, marcação que se parece com HTML.

JSX é HTML?

Não. O JSX se parece com HTML, mas é compilado em chamadas de função JavaScript que criam elementos React. É por isso que ele usa className em vez de class, nomes de atributos em camelCase e exige que toda tag seja fechada.

Posso usar React sem JSX?

Sim. O JSX é opcional: você pode chamar createElement('h1', { className: 'title' }, 'Hello') de react diretamente. Quase todo código React usa JSX porque marcação aninhada fica muito mais fácil de ler.

Por que não posso usar um if dentro do JSX?

As chaves no JSX aceitam expressões, coisas que produzem um valor, e if é uma instrução. Use um ternário (cond ? a : b), && ou calcule o valor em uma variável antes do return.

Como escrevo um comentário no JSX?

Coloque um comentário JavaScript entre chaves: {/* assim */}. Comentários HTML (<!-- -->) são erro de sintaxe no JSX.

Ilustração das linguagens de programação do Coddy

Aprenda a programar com o Coddy

COMEÇAR