JSX, kodunun içine HTML benzeri işaretleme yazmanı sağlayan bir JavaScript sözdizimi uzantısıdır. React bileşenleri ekranda ne görünmesi gerektiğini tarif etmek için JSX döndürür, bir derleme aracı da onu sıradan JavaScript fonksiyon çağrılarına derler. HTML'e benzer, ama birkaç kural farklıdır ve süslü parantezler işaretlemenin içine herhangi bir JavaScript değeri koymanı sağlar.
{} içindeki her şey JavaScript'tir: bir özellik, bir metot çağrısı, hatta bir diziyi liste öğelerine çeviren map. skills dizisine 'design' ekle; hem sayı hem de liste güncellenir.
JSX kuralları
Tek bir kök öğe döndür
Bir bileşen tek bir değer döndürür, bu yüzden JSX'inin tek bir ebeveyne ihtiyacı vardır. En üst düzeyde iki kardeş öğe sözdizimi hatasıdır. Sayfada fazladan bir <div> istemiyorsan onları bir fragment ile sar, <>...</>:
// 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>
</>
);
Gruba bir key vermen gerektiğinde uzun biçimi kullan: <Fragment key={id}>; bkz. fragment'lar.
Her etiketi kapat
HTML bazı etiketleri açık bırakmana izin verir. JSX izin vermez. Çocuğu olmayan öğeler kendilerini /> ile kapatır: <img />, <br />, <input /> ve <Avatar /> gibi kendi bileşenlerin.
className, htmlFor ve camelCase özellikler kullan
JSX özellikleri bir JavaScript nesnesinin anahtarlarına dönüşür, bu yüzden JavaScript adlandırma kurallarına uyarlar. class ve for JavaScript'te ayrılmış sözcüklerdir; JSX'in className ve htmlFor kullanmasının nedeni budur. Birden çok sözcükten oluşan özellikler ve tüm olay işleyicileri camelCase yazılır: tabIndex, maxLength, autoFocus, onClick, onChange. İki istisna tirelerini korur: aria-* ve data-* özellikleri tam olarak HTML'deki gibi yazılır.
className="field" ifadesini class="field" olarak değiştir. Etiket stilini korur, çünkü React özelliği yine de ayarlar, ama bir geliştirme derlemesi "Invalid DOM property class. Did you mean className?" uyarısını kaydeder. Önizleme bir production derlemesi gibi çalışır, bu yüzden bu uyarıyı burada görmezsin; className kullan. Bir metin özelliği tırnak kullanır (type="email"); diğer tüm değerler süslü parantez kullanır (maxLength={40}, disabled={false}).
Süslü parantezler deyim değil, ifade alır
{} içine değer üreten her şeyi yazabilirsin: bir değişken, aritmetik, bir fonksiyon çağrısı, bir ternary, &&, bir template literal. if, for ve const gibi deyimler bir değer üretmez, bu yüzden oraya giremezler. İşi return'den önce yap ya da bir ifade biçimi kullan:
Tıklamadan önce dikkatlice bak: sayfada başıboş bir 0 görünüyor. Sayı sıfır olduğunda count && <p>...</p> ifadesi 0 olarak değerlendirilir ve React sayıları, sıfırı bile, render eder. Onu count > 0 && <p>You have mail.</p> olarak değiştir, 0 kaybolur. false, null, undefined ve true hiçbir şey render etmez; &&'nin solundaki bir boolean'ın güvenli olmasının nedeni budur. Koşullu render sayfası bu kalıpları anlatıyor.
Satır içi stiller bir nesne kullanır
style özelliği bir CSS metni değil, bir JavaScript nesnesi alır. "Çift süslü parantez" görüntüsü buradan gelir: dıştaki çift "burada JavaScript var" demektir, içteki çift ise nesne literal'idir. Özellik adları camelCase'dir (backgroundColor, fontSize) ve çoğu boyut özelliğinde düz bir sayı piksel anlamına gelir.
Stil bir nesne olduğu için, diğer her değer gibi state'ten hesaplanabilir. fontSize: big ? 24 : 16 ifadesini fontSize: big ? '2em' : '1em' olarak değiştirmeyi dene: metinler birimleriyle birlikte olduğu gibi aktarılır.
Yorumlar
JSX içindeki bir yorum süslü parantezlere yazılır: {/* this is a comment */}. HTML yorumları (<!-- -->) sözdizimi hatasıdır. İşaretlemenin dışında, fonksiyon gövdesinde sıradan // yorumları her zamanki gibi çalışır.
return (
<div>
{/* The header is hidden on small screens */}
<Header />
</div>
);
HTML'i JSX'e dönüştürme
Bir bileşene HTML yapıştırmak yaygın bir ilk adımdır ve çoğu çalışır. Genellikle yapman gereken değişiklikler şunlar:
class,classNameolur;fordahtmlForolur.- Boş etiketler kendini kapatır:
<br>,<br />olur;<img src="a.png">,<img src="a.png" />olur. style="color: red; font-size: 14px",style={{ color: 'red', fontSize: 14 }}olur.- Olay özellikleri metin değil, fonksiyon alır:
onclick="save()",onClick={save}olur. - Özellik adları camelCase olur:
tabindex,tabIndexolur; SVG'ninstroke-widthözelliği destrokeWidtholur. <!-- comments -->,{/* comments */}olur.- En üst düzeydeki birden çok öğe tek bir ebeveyne ya da bir fragment'a ihtiyaç duyar.
Çevrimiçi HTML'den JSX'e dönüştürücüler bu adımları senin yerine yapar, ama bunları bilmek birini atladığında hata mesajlarını kolayca okumanı sağlar.
JSX neye derlenir
Tarayıcılar JSX çalıştıramaz. Bir derleyici (Vite ve framework'lerin senin için çalıştırdığı Babel, SWC ya da Oxc gibi) her etiketi react/jsx-runtime içinden bir fonksiyon çağrısına çevirir:
// 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' });
Küçük harfli bir etiket bir metne ('h1', bir HTML öğesi), büyük harfle başlayan ise fonksiyonuna bir referansa (Button) dönüşür; özellikler props nesnesi, içerik de children olur. Daha eski kurulumlar bunun yerine React.createElement(type, props, ...children) çağrısına derlerdi; eski dosyaların React'ten hiç söz etmeseler bile import React from 'react' ile başlamasının nedeni budur. Çağrı, React öğesi (React element) denen düz bir nesne döndürür. Birini konsola yazdırabilirsin:
Konsol, heading'in sadece veri olduğunu gösterir: bir 'h3' tipi ve bir props nesnesi. JSX'in değişkenlerde saklanabilmesi, fonksiyonlara aktarılabilmesi ve onlardan döndürülebilmesinin nedeni de budur.
JSX metni senin için kaçışlar
Süslü parantezlere koyduğun her metin HTML olarak değil, her zaman metin olarak render edilir. Bir kullanıcı bir yorum kutusuna <img src=x onerror=alert(1)> yazarsa React bir görsel etiketi oluşturmak yerine bu karakterleri ekranda gösterir. Bu, siteler arası betik çalıştırmanın (XSS) en yaygın biçimini varsayılan olarak engeller.
İlk paragraf etiketleri düz karakterler olarak yazdırır. İkincisi dangerouslySetInnerHTML kullanır; bu, kaçışlamayı atlar ve metni gerçek HTML olarak ekler, bu yüzden "our own" kalın görünür. Uzun ad bir uyarıdır: oraya yalnızca kendin ürettiğin ya da DOMPurify gibi bir temizleyiciyle temizlediğin HTML'i ver. Oraya kullanıcı girdisi vermek, JSX'in kapattığı XSS açığını yeniden açar.
Sıkça Sorulan Sorular
JSX neyin kısaltmasıdır?
JSX, JavaScript XML'in kısaltmasıdır. JavaScript kodunun içine HTML'e benzeyen işaretleme yazmanı sağlayan bir sözdizimi uzantısıdır.
JSX, HTML midir?
Hayır. JSX HTML'e benzer ama React öğeleri oluşturan JavaScript fonksiyon çağrılarına derlenir. Bu yüzden class yerine className, camelCase özellik adları kullanır ve her etiketin kapatılmasını ister.
React'i JSX olmadan kullanabilir miyim?
Evet. JSX isteğe bağlıdır: react içinden createElement('h1', { className: 'title' }, 'Hello') fonksiyonunu doğrudan çağırabilirsin. Neredeyse her React kod tabanı JSX kullanır, çünkü iç içe işaretleme çok daha kolay okunur.
JSX içinde neden if ifadesi kullanamıyorum?
JSX'teki süslü parantezler ifade (expression), yani değer üreten şeyler kabul eder; if ise bir deyimdir (statement). Bir ternary (cond ? a : b), && kullan ya da değeri return'den önce bir değişkende hesapla.
JSX'te yorum nasıl yazılır?
Bir JavaScript yorumunu süslü parantezlerle sar: {/* like this */}. HTML yorumları (<!-- -->) JSX'te sözdizimi hatasıdır.