How to show the unfinished to-do count in the page title
This example demonstrates how to show the unfinished to-do count in the page title using the useTitle
hook. It includes code in both TypeScript and JavaScript versions.
tsx
import {useEffect, useState} from "react";
import {useTitle} from "./useTitle";
interface Task {
id: number;
title: string;
isDone: boolean;
}
const appTasks: Task[] = [
{id: 1, title: "Task 1", isDone: false},
{id: 2, title: "Task 2", isDone: false},
{id: 3, title: "Task 3", isDone: false},
{id: 4, title: "Task 4", isDone: false},
{id: 5, title: "Task 5", isDone: false},
];
export default function App() {
const [tasks, setTasks] = useState<Task[]>(appTasks);
const {changeTitle} = useTitle();
useEffect(() => {
const unfinishedTasks = tasks.filter((task) => !task.isDone).length;
changeTitle(`${unfinishedTasks} pending tasks`);
}, []);
// Handle check/uncheck task
const checkTask = (id: number, isDone: boolean) => {
const updatedTasks = tasks.map((task) =>
task.id === id ? {...task, isDone} : task
);
setTasks(updatedTasks);
// Set the title depending on the number of tasks left
const unfinishedTasks = updatedTasks.filter((task) => !task.isDone).length;
const newTitle =
unfinishedTasks !== 1
? `${unfinishedTasks} pending tasks`
: `${unfinishedTasks} pending task`;
changeTitle(newTitle);
};
return (
<>
<h1>Tasks</h1>
<ul>
{tasks.map((task) => (
<li key={task.id}>
<input
type="checkbox"
checked={task.isDone}
onChange={(e) => checkTask(task.id, e.target.checked)}
/>
{task.title}
</li>
))}
</ul>
</>
);
}
typescript
import {useState} from "react";
export const useTitle = () => {
const [title, setTitle] = useState<string>(document.title);
const changeTitle = (newTitle: string) => {
document.title = newTitle;
setTitle(newTitle);
};
return {title, changeTitle};
};