Attributes and className
JSX attributes look like HTML attributes, but React treats them as props.
For built-in elements, those props usually map to DOM properties.
<button className="primary" disabled={isSaving}>
Save
</button>Strings vs JavaScript Values
Use quotes for literal strings.
<img src="/logo.svg" alt="Company logo" />Use curly braces for JavaScript values.
<img src={user.avatarUrl} alt={user.name} />
<button disabled={isSaving}>Save</button>The difference matters.
<Progress value="10" />
<Progress value={10} />The first passes a string. The second passes a number.
className
Use className instead of class.
function Alert({ type, message }) {
return <p className={`alert alert-${type}`}>{message}</p>;
}For conditional classes, build a string clearly.
function SaveButton({ isSaving }) {
const className = isSaving ? "button button-loading" : "button";
return (
<button className={className} disabled={isSaving}>
{isSaving ? "Saving..." : "Save"}
</button>
);
}Small inline expressions are fine. When the class logic grows, move it into a variable or helper.
htmlFor
Use htmlFor instead of for on labels.
function EmailField() {
return (
<label htmlFor="email">
Email
<input id="email" type="email" />
</label>
);
}This connects the label to the input for accessibility and browser focus behavior.
Event Handler Props
Events use camelCase names and receive functions.
function DeleteButton({ onDelete }) {
return (
<button onClick={onDelete}>
Delete
</button>
);
}Do not call the handler while rendering unless you are intentionally creating a function.
// Wrong: calls deleteItem immediately during render
<button onClick={deleteItem(id)}>Delete</button>
// Right: passes a function React can call later
<button onClick={() => deleteItem(id)}>Delete</button>style Uses an Object
The style prop receives an object, not a CSS string.
function Notice() {
return (
<p style={{ color: "tomato", fontWeight: "bold" }}>
Unsaved changes
</p>
);
}CSS property names are camelCase.
// CSS: background-color
// JSX style object: backgroundColor
<div style={{ backgroundColor: "black" }} />Inline styles can be useful for dynamic values, but regular CSS classes are usually better for reusable styling.
Boolean Attributes
Boolean props should usually be passed as booleans.
<button disabled={isSaving}>Save</button>
<input required />Writing disabled="false" passes a string. In normal HTML, a present boolean attribute can still behave as enabled or disabled based on the browser property mapping, but in React code it is clearer and safer to pass an actual boolean.
ARIA and data Attributes
ARIA and data-* attributes keep their original names.
<button
aria-expanded={isOpen}
aria-controls="settings-panel"
data-testid="settings-toggle"
>
Settings
</button>These attributes are designed to be dash-cased, so React preserves that convention.
Spreading Props
The spread operator can forward props.
function TextInput(props) {
return <input className="field" {...props} />;
}Use prop spread carefully. It can make code concise, but it can also hide what a component accepts.
Order matters:
// Caller can override type
<input type="text" {...props} />
// Component forces type to text
<input {...props} type="text" />Common Mistakes
- Using
classinstead ofclassName. - Using
forinstead ofhtmlFor. - Passing
"false"or"0"when the component expects booleans or numbers. - Calling an event handler immediately with
onClick={save()}. - Using a CSS string in
styleinstead of an object. - Spreading props after important defaults and accidentally overriding them.
What is wrong with onClick={handleSave()} in most React components?
Mini Challenge
Fix this JSX:
function ProfileLink({ user, isActive, openProfile }) {
return (
<a class="profile-link" href="/profile" onclick={openProfile(user.id)} style="font-weight: bold">
{user.name}
</a>
);
}Make the attributes valid JSX, pass a function to the click handler, and use a style object or class name for styling.
Recap
JSX attributes are JavaScript-friendly props. Use className, htmlFor, camelCase events, boolean values in braces, object-based styles, and careful prop spreading.