Skip to content
This repository was archived by the owner on Sep 14, 2022. It is now read-only.

Commit 5988397

Browse files
committed
feat: debounce code editing (fixes #3)
1 parent 7c086d7 commit 5988397

File tree

4 files changed

+35
-10
lines changed

4 files changed

+35
-10
lines changed

src/components/Editor.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React, { useState, useEffect, useRef } from "react";
22
import CodeMirror from "codemirror";
3+
import { debounce } from "@/shared/debounce";
4+
import { EDITING_TIMEOUT } from "@/components/constants";
35
import type { FC } from "react";
46
import type { Linter } from "eslint";
57
import type { TextMarker, Editor as CodeEditor } from "codemirror";
@@ -27,14 +29,16 @@ export const Editor: FC<Props> = (props) => {
2729
const [errorMarkers, setErrorMarkers] = useState<TextMarker[]>([]);
2830
const ref = useRef<HTMLTextAreaElement>(null);
2931

32+
const changeHandler = debounce(() => {
33+
const value = editor?.getValue() ?? "";
34+
props.onChange?.(value);
35+
setText(value);
36+
}, EDITING_TIMEOUT);
37+
3038
useEffect(() => {
3139
if (ref.current) {
3240
editor = CodeMirror.fromTextArea(ref.current, CODE_MIRROR_OPTIONS);
33-
editor.on("change", () => {
34-
const value = editor?.getValue() ?? "";
35-
props.onChange?.(value);
36-
setText(value);
37-
});
41+
editor.on("change", changeHandler);
3842
}
3943
}, []);
4044

src/components/RuleConfig.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React, { useState, useEffect, useRef } from "react";
22
import CodeMirror from "codemirror";
3+
import { EDITING_TIMEOUT } from "@/components/constants";
4+
import { debounce } from "@/shared/debounce";
35
import type { FC } from "react";
46
import type { Linter } from "eslint";
57
import "codemirror/lib/codemirror.css";
@@ -33,11 +35,14 @@ export const RuleConfig: FC<Props> = (props) => {
3335
ref.current,
3436
CODE_MIRROR_OPTIONS
3537
);
36-
codeMirror.on("change", () => {
37-
const value = codeMirror.getValue();
38-
props.onChange?.(value);
39-
setText(value);
40-
});
38+
codeMirror.on(
39+
"change",
40+
debounce(() => {
41+
const value = codeMirror.getValue();
42+
props.onChange?.(value);
43+
setText(value);
44+
}, EDITING_TIMEOUT)
45+
);
4146
}
4247
}, []);
4348

src/components/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { Linter } from "eslint";
22

3+
export const EDITING_TIMEOUT = 300;
4+
35
export const DEFAULT_CODE = `
46
async function invalidInTryCatch1() {
57
try {

src/shared/debounce.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
type Func<T = unknown> = (...args: T[]) => void;
2+
3+
export function debounce(func: Func, delayMs: number): Func {
4+
let timer: null | ReturnType<typeof setTimeout> = null;
5+
return function call(...args: Parameters<Func>) {
6+
if (timer) {
7+
clearTimeout(timer);
8+
}
9+
timer = setTimeout(() => {
10+
timer = null;
11+
func(...args);
12+
}, delayMs);
13+
};
14+
}

0 commit comments

Comments
 (0)