You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Added detailed explanations of how JSX handles HTML attributes, including differences in attribute names, boolean attributes, inline styles, data and ARIA attributes, and tips for converting HTML to JSX.
Copy file name to clipboardExpand all lines: src/content/learn/writing-markup-with-jsx.md
+99Lines changed: 99 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -222,6 +222,102 @@ For historical reasons, [`aria-*`](https://developer.mozilla.org/docs/Web/Access
222
222
223
223
</Pitfall>
224
224
225
+
226
+
227
+
### How React Handles HTML Attributes {/*how-react-handles-html-attributes*/}
228
+
229
+
JSX looks a lot like HTML, but a few attributes work slightly differently because JSX maps to JavaScript and DOM properties. This short reference explains the common differences and shows examples you can copy.
230
+
231
+
### Attribute name differences
232
+
233
+
Some HTML attribute names are either reserved words in JavaScript or differ from the DOM property names. Use the React/JSX name when writing JSX:
234
+
235
+
```jsx
236
+
{/* use `className` instead of `class` */}
237
+
<div className="container" />
238
+
239
+
{/* use `htmlFor` instead of `for` */}
240
+
<label htmlFor="email">Email</label>
241
+
```
242
+
243
+
### Boolean attributes
244
+
245
+
In HTML, boolean attributes are represented by their presence. In JSX, you pass explicit boolean values—but JSX also supports the shorthand form (which means `true`):
246
+
247
+
```html
248
+
<!-- HTML -->
249
+
<input disabled />
250
+
```
251
+
```jsx
252
+
// JSX (explicit boolean)
253
+
<input disabled={true} />
254
+
255
+
// JSX (shorthand, equivalent to true)
256
+
<input disabled />
257
+
```
258
+
259
+
### Inline styles
260
+
261
+
HTML uses a CSS string. JSX uses a JavaScript object with camelCased property names:
Numeric values (like lineHeight, zIndex) can be written as numbers
271
+
```jsx
272
+
<div style={{ lineHeight: 1.5, zIndex: 10 }} />
273
+
```
274
+
275
+
### Data and ARIA attributes
276
+
277
+
React preserves data-* and aria-* attributes exactly as they appear in HTML. These must remain dash-cased:
278
+
```jsx
279
+
<div
280
+
data-user-id="123"
281
+
data-active="true"
282
+
aria-label="Close Button"
283
+
/>
284
+
```
285
+
These attributes are ideal for accessibility and for storing custom data.
286
+
287
+
### Unknown or invalid attributes
288
+
289
+
React will not add invalid or unknown attributes to the DOM:
290
+
```jsx
291
+
// Ignored: not a valid DOM attribute
292
+
<div customAttribute="hello" />
293
+
294
+
// ✔ Correct: custom data attribute
295
+
<div data-qa="alert-box" />
296
+
```
297
+
If you intentionally want to pass unknown props (for example, in wrapper components), use the spread operator:
298
+
299
+
```jsx
300
+
function Button({ children, ...rest }) {
301
+
return <button {...rest}>{children}</button>;
302
+
}
303
+
304
+
// usage
305
+
<Button data-track="1" disabled>Click</Button>
306
+
```
307
+
308
+
### Tips & common gotchas
309
+
310
+
- Use DOM property names (`className`, `htmlFor`, `defaultValue`) in JSX.
311
+
- Boolean attributes should use `true` or `false`, not strings.
312
+
- `data-*` and `aria-*` attributes stay the same in JSX.
313
+
- Invalid attributes are removed from the DOM—use `data-*` for custom values.
314
+
- Always double-check `class` → `className`, `for` → `htmlFor`, and convert `style` to an object when moving HTML to JSX.
315
+
316
+
317
+
318
+
319
+
320
+
225
321
### Pro-tip: Use a JSX Converter {/*pro-tip-use-a-jsx-converter*/}
226
322
227
323
Converting all these attributes in existing markup can be tedious! We recommend using a [converter](https://transform.tools/html-to-jsx) to translate your existing HTML and SVG to JSX. Converters are very useful in practice, but it'sstillworthunderstandingwhatisgoingonsothatyoucancomfortablywriteJSXonyourown.
@@ -351,3 +447,6 @@ export default function Bio() {
0 commit comments