Simple Blog Post Editor
Create a text input area where users can enter a title and content for a blog post, and submit it with a button.
Solution
Explanation
The HTML Structure
A form
element with an onSubmit
that calls handleSubmit
.
Note there are labels and inputs. Reminder that it is the id
attribute that links to the label via htmlFor
. The name
attribute is the key for the value when the form data is received.
Each input is linked to a separate onChange
function. The final input has a type of submit
.
onChange functions
Each on change function is connected with its relevant state
. Each function updates state.
handleSubmit function
The default behaviour of a JS Form
element is to send the data and refresh the page. To stop that from happening, we use event.preventDefault
.
The data is then be processed. In this case, an alert has been created.
Notice that both the title and content are reset to a blank string afterwards.
Code
import { ChangeEvent, FormEvent, useState } from "react";
import styles from "./Solution.module.css";
const Solution = () => {
const [title, setTitle] = useState<string>("");
const [content, setContent] = useState<string>("");
function handleTitle(event: ChangeEvent<HTMLInputElement>): void {
setTitle(event.target.value);
}
function handleContent(event: ChangeEvent<HTMLTextAreaElement>): void {
setContent(event.target.value);
}
function handleSubmit(event: FormEvent<HTMLFormElement>): void {
event.preventDefault();
alert(`Title: ${title}, \nContent: ${content}`);
setTitle("");
setContent("");
}
return (
<form onSubmit={handleSubmit} className={styles.container}>
<label className={styles.label} htmlFor="title">
Title
</label>
<input
required
onChange={handleTitle}
value={title}
className={styles.input}
type="text"
name="title"
id="title"
/>
<label className={styles.label} htmlFor="content">
Content
</label>
<textarea
required
onChange={handleContent}
value={content}
rows={5}
className={styles.input}
name="content"
id="content"
/>
<input
aria-label="Submit post"
className={styles.button}
type="submit"
value="Post"
/>
</form>
);
};
export default Solution;
Styling
.container {
display: flex;
flex-direction: column;
max-width: 350px;
border: 1px solid black;
padding: 15px;
gap: 15px;
}
.label {
display: block;
}
.input {
padding: 5px;
}
.button {
padding: 5px;
cursor: pointer;
}