What is a component in React and what are props?
Show answer — try answering out loud first
A component is a function that receives props and returns JSX: a reusable piece of UI. Props are the data the parent component passes to the child; they are read-only and always flow in one direction, from parent to child.
Think of a component as a LEGO brick: you define it once and use it many times with different data. A React app is a tree of components composed inside one another. Props (from properties) are the mechanism for passing information to a component:
- They're like a function's arguments: the parent "calls" the child with certain values.
- They're read-only: a component should never modify its props. If it needs data that changes, that's state, not props.
- Unidirectional flow: data flows down from parent to child. If a child needs to "notify" something upward, the parent passes it a function via props and the child calls it.
- Composition: instead of inheritance, React favors composing small components. The special
childrenprop lets a component wrap others. - With TypeScript: typing the props with a
typedocuments the component's contract and prevents errors when using it.
import type { ReactNode } from "react";
// Props are typed with a type: this is the component's "contract"
type SaludoProps = { nombre: string; edad?: number };
function Saludo({ nombre, edad }: SaludoProps) {
return <p>Hola, {nombre}{edad !== undefined && ` (${edad} años)`}</p>;
}
// Composition: Tarjeta doesn't know what it contains, it just wraps its children
type TarjetaProps = { titulo: string; children: ReactNode };
function Tarjeta({ titulo, children }: TarjetaProps) {
return (
<section className="tarjeta">
<h2>{titulo}</h2>
{children}
</section>
);
}
function App() {
return (
<Tarjeta titulo="Equipo">
{/* The same component, reused with different props */}
<Saludo nombre="Ana" edad={28} />
<Saludo nombre="Luis" />
</Tarjeta>
);
}
// Expected output:
// Equipo / Hola, Ana (28 años) / Hola, Luis
Trying to mutate props inside the child:
// BAD: reassigning the prop doesn't re-render and breaks the contract
function Contador({ contador }: { contador: number }) {
return <button onClick={() => (contador = contador + 1)}>{contador}</button>;
}
// GOOD: the child notifies with a function; the parent (data owner) updates
type Props = { contador: number; onIncrementar: () => void };
function ContadorBien({ contador, onIncrementar }: Props) {
return <button onClick={onIncrementar}>{contador}</button>;
}
"A component is a function that receives props and returns JSX; it's the basic unit of reuse in React. Props are the data the parent passes to the child, like a function's arguments, and they're read-only: a component should never modify them. Data flows in a single direction, from parent to child, and when the child needs to communicate something upward, it receives a function via props and runs it. Instead of inheritance, React uses composition: I build complex interfaces by combining small components, often with the
childrenprop."
Create a Boton component that receives via props a texto: string, an optional prop deshabilitado?: boolean, and a function onPresionar: () => void. Use it from an App component that shows two buttons: one active and one disabled.
See solution
type BotonProps = {
texto: string;
deshabilitado?: boolean;
onPresionar: () => void;
};
function Boton({ texto, deshabilitado = false, onPresionar }: BotonProps) {
return (
<button disabled={deshabilitado} onClick={onPresionar}>
{texto}
</button>
);
}
function App() {
return (
<>
<Boton texto="Guardar" onPresionar={() => console.log("guardado")} />
<Boton texto="Eliminar" deshabilitado onPresionar={() => {}} />
</>
);
}