Skip to content

Commit 252c643

Browse files
committed
fix: CommandInput ref 깨짐
[#297]
1 parent 09a513d commit 252c643

File tree

3 files changed

+29
-23
lines changed

3 files changed

+29
-23
lines changed

packages/frontend/src/components/terminal/CommandInput.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@ interface CommandInputProps {
1616
handleInput: KeyboardEventHandler;
1717
}
1818

19-
type ForwardRefType = Pick<HTMLSpanElement, "focus" | "scrollIntoView">;
19+
export type CommandInputForwardRefType = {
20+
focus: HTMLSpanElement["focus"];
21+
scrollIntoView: HTMLSpanElement["scrollIntoView"];
22+
clear: () => void;
23+
};
2024

21-
const CommandInput = forwardRef<ForwardRefType, CommandInputProps>(
25+
const CommandInput = forwardRef<CommandInputForwardRefType, CommandInputProps>(
2226
({ gitRef, handleInput }, ref) => {
2327
const inputRef = useRef<HTMLSpanElement>(null);
2428

@@ -31,6 +35,14 @@ const CommandInput = forwardRef<ForwardRefType, CommandInputProps>(
3135
scrollIntoView(arg) {
3236
scrollIntoViewRef(inputRef, arg);
3337
},
38+
clear() {
39+
const $element = inputRef.current;
40+
if (!$element) {
41+
return;
42+
}
43+
44+
$element.textContent = "";
45+
},
3446
}),
3547
[],
3648
);

packages/frontend/src/components/terminal/Terminal.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { type KeyboardEventHandler, forwardRef } from "react";
33
import { ENTER_KEY } from "../../constants/event";
44
import type { TerminalContentType } from "../../types/terminalType";
55

6-
import CommandInput from "./CommandInput";
6+
import CommandInput, { CommandInputForwardRefType } from "./CommandInput";
77
import * as styles from "./Terminal.css";
88
import TerminalContent from "./TerminalContent";
99

@@ -13,7 +13,7 @@ interface TerminalProps {
1313
onTerminal: (input: string) => void;
1414
}
1515

16-
const Terminal = forwardRef<HTMLSpanElement, TerminalProps>(
16+
const Terminal = forwardRef<CommandInputForwardRefType, TerminalProps>(
1717
({ gitRef, contentArray, onTerminal }, ref) => {
1818
const handleStandardInput: KeyboardEventHandler = async (event) => {
1919
const {

packages/frontend/src/pages/quizzes/[id].page.tsx

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import axios, { isAxiosError } from "axios";
22
import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from "next";
33
import { useRouter } from "next/router";
4-
import { RefObject, useEffect, useReducer, useRef, useState } from "react";
4+
import { useEffect, useReducer, useRef, useState } from "react";
55

66
import { quizAPI } from "../../apis/quiz";
77
import { Editor } from "../../components/editor";
@@ -10,6 +10,7 @@ import { Graph } from "../../components/graph";
1010
import { SolvedModal, useSolvedModal } from "../../components/quiz";
1111
import { QuizGuide } from "../../components/quiz/QuizGuide";
1212
import { Terminal } from "../../components/terminal";
13+
import { CommandInputForwardRefType } from "../../components/terminal/CommandInput";
1314
import { BROWSWER_PATH } from "../../constants/path";
1415
import {
1516
UserQuizStatusActionType,
@@ -25,7 +26,6 @@ import {
2526
} from "../../reducers/terminalReducer";
2627
import { Categories, Quiz, QuizGitGraphCommit } from "../../types/quiz";
2728
import { TerminalContentType } from "../../types/terminalType";
28-
import { focusRef, scrollIntoViewRef } from "../../utils/refObject";
2929
import { isString } from "../../utils/typeGuard";
3030

3131
import * as styles from "./quiz.css";
@@ -44,7 +44,7 @@ export default function QuizPage({ quiz }: { quiz: Quiz }) {
4444
const [{ terminalMode, editorFile, contentArray }, terminalDispatch] =
4545
useReducer(terminalReducer, initialTerminalState);
4646

47-
const terminalInputRef = useRef<HTMLSpanElement>(null);
47+
const terminalInputRef = useRef<CommandInputForwardRefType>(null);
4848

4949
const fetchGitGraphDataRef = useRef(async (curId: number) => {
5050
try {
@@ -131,8 +131,8 @@ export default function QuizPage({ quiz }: { quiz: Quiz }) {
131131
await quizAPI.resetQuizById(numId);
132132
fetchGitGraphDataRef?.current(numId);
133133
terminalDispatch({ type: TerminalActionTypes.reset });
134-
clearTextContent(terminalInputRef);
135-
focusRef(terminalInputRef);
134+
terminalInputRef.current?.clear();
135+
terminalInputRef.current?.focus();
136136
userQuizStatusDispatcher({
137137
type: UserQuizStatusActionType.ResetQuizById,
138138
id: numId,
@@ -150,14 +150,17 @@ export default function QuizPage({ quiz }: { quiz: Quiz }) {
150150
fetchGitGraphDataRef?.current(+id);
151151
}
152152
terminalDispatch({ type: TerminalActionTypes.reset });
153-
clearTextContent(terminalInputRef);
154-
focusRef(terminalInputRef);
153+
terminalInputRef.current?.clear();
154+
terminalInputRef.current?.focus();
155155
}, [id]);
156156

157157
useEffect(() => {
158-
scrollIntoViewRef(terminalInputRef);
159-
clearTextContent(terminalInputRef);
160-
focusRef(terminalInputRef);
158+
const $terminalInput = terminalInputRef.current;
159+
if (!$terminalInput) return;
160+
161+
$terminalInput.scrollIntoView();
162+
$terminalInput.clear();
163+
$terminalInput.focus();
161164
}, [contentArray]);
162165

163166
const { barRef, topRef, handleBarHover } = useResizableSplitView();
@@ -239,15 +242,6 @@ export const getStaticPaths = (async () => {
239242
return { paths, fallback: "blocking" };
240243
}) satisfies GetStaticPaths;
241244

242-
function clearTextContent<T extends Element>(ref: RefObject<T>) {
243-
const $element = ref.current;
244-
if (!$element) {
245-
return;
246-
}
247-
248-
$element.textContent = "";
249-
}
250-
251245
function isEditorMode(terminalMode: "editor" | "command") {
252246
return terminalMode === "editor";
253247
}

0 commit comments

Comments
 (0)