CPRG-306 Week 5
Interactivity with Forms
Agenda
- Survey Feedback
- Review HTML form elements
- JavaScript: event object, preventDefault
- React: conditional rendering, controlled components
- Demo: Create a controlled component.
Survey Feedback
- Likes
- Teaching style / lectures (e.g. half-theory / half-code)
- Extra materials
- Video recordings
Survey Feedback, cont'd
- Suggestions for improvement:
- More practice problems
- See further reading section
- Upcoming project
- Additional explanation of page rendering
- More practice problems
Page Rendering Flow
- Server-Side Rendering
- User navigates to a URL → server receives the request.
- Components rendered on the server
- Output: Static HTML + placeholders for client components.
- Client-Side Hydration
- Initial Load: Browser displays HTML immediately
- JavaScript Bundles: Downloaded in the background.
- Hydration: React "revives" static HTML with interactivity.
Hydration
- Process where React attaches to server-rendered HTML.
- Matches DOM nodes to React components
- Initializes state/event listeners
- Makes the page interactive
Why It Matters
- Combines speed of SSR with interactivity of CSR
- No "flash of empty content" (avoids pure client-side rendering).
Client-Side Interactivity
Post-Hydration
- Client components take over (e.g., useState, useEffect).
- User clicks a button → onClick fires.
- useState updates component state.
- React re-renders only the changed parts (reconciliation).
HTML: Forms
- Form elements
<form>
- container for form controls<input>
- text, password, radio, checkbox, etc.<textarea>
- multi-line text input<select>
- drop-down list<button>
- submit, reset, or generic button
HTML Forms Example
<form action="/send" method="post">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required />
<label for="email">Email:</label>
<input type="email" id="email" name="email" required />
<label for="message">Message:</label>
<textarea id="message" name="message" required></textarea>
<button type="submit">Submit</button>
</form>
In this example, the form will be submitted to /send
using the POST method.
JavaScript: Event Object
-
Event object is passed to event handlers
-
Contains information about the event
type
- event type, e.g.click
,submit
target
- element that triggered the event, e.g. button
-
target
property is useful for form validation -
e.g.
event.target.value
to get the value of an input field
JavaScript: Event Object Example
const getValues = (event) => {
// Get the value of the input field
console.log(event.target.value);
};
// In JSX, pass the event object to the event handler
<input type="text" onChange={(e) => getValues(e)} />;
JavaScript: preventDefault
- Prevents the default behavior of an event
- e.g. preventing form submission is useful for React applications
const handleSubmit = (event) => {
event.preventDefault();
// Do something with the form data
// Form will not be submitted, i.e. /send will not be called
};
JavaScript: &&
- Logical AND operator, evaluates to true if both operands are true
- If the first operand is false, the second operand is not evaluated. Why?
const a = () => {
console.log("a");
return true;
};
const b = () => {
console.log("b");
return true;
};
const c = () => {
console.log("c");
return false;
};
a() && b(); // a, b
a() && c(); // a, c
c() && a(); // c
React: Conditional Rendering
- You cannot put an
if
statement inside JSX - Use conditional rendering with the logical AND operator or ternary operator
export default function Toggle() {
const [show, setShow] = useState(false);
return (
<div>
<button onClick={() => setShow(!show)}>Toggle</button>
{show && <p>Visible</p>}
</div>
);
}
React: Conditional Rendering, cont'd
- Conditional rendering can be done with the ternary operator
- Useful for rendering different components based on a condition
condition ? true : false
- if condition is true, render true, otherwise render false
export default function Alert({ type }) {
return (
<div className={type === "success" ? "bg-green-100" : "bg-red-100"}>
{type === "success" ? "Success" : "Error"}
</div>
);
}
Template Literals
- Use backticks to create a template literal
- Use
${}
to insert a variable or expression - Better than concatenation because it's easier to read
const name = "Alice";
console.log(`Hello, ${name}!`);
- Conditional rendering with template literals
export default function Alert({ type }) {
return (
<div
className={`text-lg ${
type === "success" ? "bg-green-100" : "bg-red-100"
} p-2`}
>
{type === "success" ? "Success" : "Error"}
</div>
);
}
React: Controlled Components
- Controlled components are form elements whose value is controlled by React
- Use the
useState
hook to manage the state of form elements - Use the
onChange
event handler to update the state - Use the
value
attribute to set the value of the form element - Use the
onSubmit
event handler to handle form submission
export default function ControlledComponent() {
const [favouriteWord, setFavouriteWord] = useState("");
const handleSubmit = (event) => {
event.preventDefault();
// Do something with the form data
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={favouriteWord}
onChange={(e) => setFavouriteWord(e.target.value)}
/>
<p>Your favourite word is: {favouriteWord}</p>
<button type="submit">Submit</button>
</form>
);
}
Demo: Controlled Component
- Create a form to add a dog with name, breed, and age
- Use the useState hook to manage state of each form control
- Use the onChange event handler to update state
- Upon submission, create a dog object and display it in the console
- Add validation using conditional rendering