Props & children; event handlers; refs
Define typed props and children; wire up event handlers safely; create and use refs to access DOM nodes.
Props & children; event handlers; refs is a free TypeScript Academy lesson on CoddyKit. This is lesson 1 of 3. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, and your progress syncs across the web and the CoddyKit app. The TypeScript Academy course includes 3 lessons in total.
Intro
Goal: Build typed React components: define props (with children), attach event handlers with precise types, and focus an input using refs.
- Typed props interfaces
- Event handler types
- Refs for DOM access
Typed props
Declare a props interface; use optional props and narrow with union literals. Keep defaults inside the component.
import React from "react"
interface BadgeProps {
text: string
color?: "primary" | "success" | "warning"
}
export function Badge({ text, color = "primary" }: BadgeProps) {
const bg = color === "success" ? "#16a34a" : color === "warning" ? "#d97706" : "#2563eb"
return <span style={{ backgroundColor: bg, color: "white", padding: 4, borderRadius: 6 }}>{text}</span>
}
export default function App() {
return (
<div style={{ display: "grid", gap: 8 }}>
<Badge text="Saved" color="success" />
<Badge text="Warn" color="warning" />
</div>
)
}Children
Use PropsWithChildren<T> (or React.PropsWithChildren) to add a typed children slot to your props.
import React, { PropsWithChildren } from "react"
type CardProps = PropsWithChildren<{ title: string }>
function Card({ title, children }: CardProps) {
return (
<div style={{ border: "1px solid #e5e7eb", padding: 12, borderRadius: 8 }}>
<h3 style={{ margin: 0 }}>{title}</h3>
<div>{children}</div>
</div>
)
}
export default function App() {
return (
<Card title="Dashboard">
<p>Children are typed automatically.</p>
</Card>
)
}Event handlers
Prefer React.MouseEvent<Element> and React.ChangeEvent<HTMLInputElement>. They expose typed target/currentTarget.
import React from "react"
export default function App() {
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
console.log("clicked", e.currentTarget.name)
}
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
console.log("value", e.target.value)
}
return (
<div style={{ display: "grid", gap: 8 }}>
<input name="n" onChange={handleChange} placeholder="Type here" />
<button name="ok" onClick={handleClick}>Confirm</button>
</div>
)
}Refs: DOM access
useRef<HTMLInputElement>(null) keeps a nullable ref; use optional chaining to access the DOM node safely.
import React, { useRef } from "react"
export default function App() {
const inputRef = useRef<HTMLInputElement>(null)
const focusInput = () => {
inputRef.current?.focus()
}
return (
<div style={{ display: "grid", gap: 8 }}>
<input ref={inputRef} placeholder="Focus me" />
<button onClick={focusInput}>Focus</button>
</div>
)
}Forwarding refs
forwardRef lets parents access a child DOM node. Provide the element type for precise typing.
import React, { forwardRef } from "react"
type TextInputProps = { label: string }
const TextInput = forwardRef<HTMLInputElement, TextInputProps>(function TextInput({ label }, ref) {
return (
<label style={{ display: "grid", gap: 4 }}>
<span>{label}</span>
<input ref={ref} />
</label>
)
})
export default function App() {
const setRef = (el: HTMLInputElement | null) => { if (el) el.focus() }
return <TextInput ref={setRef} label="Auto focus" />
}Events typing check
Quick check: What is a correct type for a button click handler?
Recap
Recap: Define props (with children), type your events precisely, and use refs (including forwardRef) to access DOM nodes safely.
Learn TypeScript with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 101
- Lessons
- 352
Frequently Asked Questions
Is the “Props & children; event handlers; refs” lesson free?
Yes — the full text of “Props & children; event handlers; refs” is free to read here on the web. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO. The TypeScript Academy course includes 3 lessons in total.
What will I learn in “Props & children; event handlers; refs”?
Define typed props and children; wire up event handlers safely; create and use refs to access DOM nodes. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start TypeScript Academy?
No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 1 of 3.
How long does the “Props & children; event handlers; refs” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this TypeScript Academy lesson?
Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Props & children; event handlers; refs
- State & reducers; Context typing
- Component generics — intro