Components
The core building block of React-driven user interface is a Component. Everything is a component at some level. Each component has logic and appearance. The appearance is written in JSX, which stands for JavaScript XML.
- React components always start with a capital letter.
- All tags in React components must close, XHTML-style. This includes
img
andbr
tags. - A React component must always return one tag. A component that has multiple
tags must be wrapped in something, even if itโs just
<></>
- The HTML
class
property is represented withclassName
instead
The <></>
syntax is short-form for Fragment
. The longer form is required if
you ever need to pass props.
Dynamic Dataโ
Curly brackets are used to escape back into JavaScript.
return <h1>{user.name}</h1>;
(See Displaying Data for more complex examples)
We can conditionally render sections by escaping with curly brackets and using ternary operators.
// Show if true
<div>
{ loggedIn && (
<p>Hi there, {user.name}</p>
)}
</div>
// if-else
<div>
{ loggedIn ? (
<p>Hi there, {user.name}</p>
) : (
<p>You are not logged in</p>
)}
</div>
Listsโ
Lists should always have a key
attribute, which is used to keep track of what
a particular child actually is.
users.map((user) => <li key={user.id}>{user.name}</li>);
Keys must be unique amongst their siblings, and must not change.
Avoid using the array index for the key. If the list ever needs to be rearranged, then the key will change.
Further reading: Rendering Lists
Stateโ
useState
can be used to track
state. The two returned values must be set using const
.
// value, and function used to set the value
const [user, setUser] = useState(initialValue);
State is local to the component. If you want to share state, pull the state up higher in the component hierarchy.
Eventsโ
function MyComponent() {
// Yes, this is a function inside a function. JavaScript is weird like that.
function handleClick() {
console.log("Got it");
}
return <button onClick={handleClick}>Click me</button>;
}
Propsโ
Properties (props) are declared in the function. Bonus points for typedefโing them.
interface UserDetailsProps {
name: string;
age: number;
status: "Single" | "It's complicated" | "In a relationship" | undefined;
}
function UserDetails({ name, age, status }: Readonly<UserDetailsProps>) {
return (
<div className="card">
<h3>{name}</h3>
<p className="text-sm">
{age} years old &em; {status}
</p>
</div>
);
}
Props are always a single object passed into the component, but are commonly accessed via destructuring. This is optional but recommended; if thereโs a reason to, you could just work directly with the props parameter.
function UserDetails(props) {}
Defaults can be set when destructuring. The default value is used only when
the value is undefined
. Other values, including null
or 0
will be accepted
as-is.
function UserDetails({ age = 42 }) {}
Props can be passed to children using spread syntax, but is generally a sign that youโre doing something wrong.
Props are immutable. If a prop changes, then the component will need to be
rerendered by the parent component. setState
can be used for internal
component memory, if needed.
Childrenโ
The contents of a component can be accessed using the children
prop. This is a
prop like any other value that you might pass in.