Skip to content

Commit a53ffed

Browse files
committed
using custom debounce for searach and que navigation
1 parent bfee41c commit a53ffed

File tree

4 files changed

+67
-10
lines changed

4 files changed

+67
-10
lines changed

app/page.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@ import { useState } from "react";
44
import type { NextPage } from "next";
55
import NameLink from "@azure-fundamentals/components/NameLink";
66
import exams from "@azure-fundamentals/lib/exams.json";
7+
import useDebounce from "@azure-fundamentals/hooks/useDebounce";
78

89
const Home: NextPage = () => {
910
const [searchTerm, setSearchTerm] = useState("");
11+
const debouncedSearchTerm = useDebounce(searchTerm, 300); // 300ms debounce delay
1012

1113
const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
1214
setSearchTerm(event.target.value);
1315
};
1416

1517
const filteredExams = exams.filter((exam) =>
16-
exam.name.toLowerCase().includes(searchTerm.toLowerCase()),
18+
exam.name.toLowerCase().includes(debouncedSearchTerm.toLowerCase()),
1719
);
1820

1921
return (
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import useDebounce from "@azure-fundamentals/hooks/useDebounce";
2+
import { useState, useEffect } from "react";
3+
4+
interface Props {
5+
totalQuestions: number;
6+
currentQuestionIndex: number;
7+
handleNextQuestion: (index: number) => void;
8+
}
9+
10+
const NumberInputComponent: React.FC<Props> = ({
11+
totalQuestions,
12+
currentQuestionIndex,
13+
handleNextQuestion,
14+
}) => {
15+
const [inputValue, setInputValue] = useState(currentQuestionIndex);
16+
const debouncedInputValue = useDebounce(inputValue, 1000);
17+
18+
useEffect(() => {
19+
if (debouncedInputValue !== currentQuestionIndex) {
20+
handleNextQuestion(debouncedInputValue);
21+
}
22+
}, [debouncedInputValue, currentQuestionIndex, handleNextQuestion]);
23+
24+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
25+
setInputValue(Number(e.target.value));
26+
};
27+
28+
return (
29+
<input
30+
className="w-[40px] text-white rounded-l-md border outline-0 border-slate-700 bg-slate-900 text-center text-md [-moz-appearance:_textfield] [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none"
31+
type="number"
32+
min={0}
33+
max={totalQuestions}
34+
value={inputValue}
35+
onChange={handleChange}
36+
/>
37+
);
38+
};
39+
40+
export default NumberInputComponent;

components/QuizForm.tsx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Question } from "./types";
44
import Image from "next/image";
55
import SelectionInput from "./SelectionInput";
66
import { Button } from "./Button";
7+
import NumberInputComponent from "./NumberInputComponent";
78

89
type Props = {
910
isLoading: boolean;
@@ -218,15 +219,10 @@ const QuizForm: FC<Props> = ({
218219
<span className="absolute text-white opacity-10 font-bold text-6xl bottom-0 -z-[1] select-none">
219220
Q&A
220221
</span>
221-
<input
222-
className="w-[40px] text-white rounded-l-md border outline-0 border-slate-700 bg-slate-900 text-center text-md [-moz-appearance:_textfield] [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none"
223-
type="number"
224-
min={0}
225-
max={totalQuestions}
226-
value={currentQuestionIndex}
227-
onChange={(e) => {
228-
handleNextQuestion(Number(e.target.value));
229-
}}
222+
<NumberInputComponent
223+
totalQuestions={totalQuestions}
224+
currentQuestionIndex={currentQuestionIndex}
225+
handleNextQuestion={handleNextQuestion}
230226
/>
231227
<p className="text-white text-md font-semibold text-center w-[40px] rounded-r-md border bg-slate-800 border-slate-700">
232228
{totalQuestions}

hooks/useDebounce.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { useState, useEffect } from "react";
2+
3+
function useDebounce<T>(value: T, delay: number): T {
4+
const [debouncedValue, setDebouncedValue] = useState<T>(value);
5+
6+
useEffect(() => {
7+
const handler = setTimeout(() => {
8+
setDebouncedValue(value);
9+
}, delay);
10+
11+
return () => {
12+
clearTimeout(handler);
13+
};
14+
}, [value, delay]);
15+
16+
return debouncedValue;
17+
}
18+
19+
export default useDebounce;

0 commit comments

Comments
 (0)