Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ const CommentInputBox = ({
const { openModal, closeModal } = useModal();

const replyCreateMode = mode.type === 'reply' && mode.action === 'create';

const handleFocus = () => {
if (mode.type === 'reset') {
Copy link
Member

@hansoojeongsj hansoojeongsj Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

댓글 인풋이 포커스되지 않은 상태에서 사진을 먼저 선택하면, 사진만 업로드된 상태가 mode.type === 'reset'이라 인풋 포커스 시 mode가 변경되면서 상태가 초기화될 것 같습니당

그래서 사진이 이미 선택된 경우에는 mode를 변경하지 않도록
if (mode.type === 'reset' && !selectedFile) {
이런 식으로 조건을 추가하면 해결될 것 같은데, 더 좋은 방향이 있으면 그쪽으로 수정해주셔도 좋습니다~ 🙂

Copy link
Member Author

@jeonghoon11 jeonghoon11 Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋은 코드리뷰 감사해요! 이미지쪽 케이스를 생각을 못 했네요. 수정님 말씀대로 댓글 인풋 포커스되지 않은 상태에서 사진을 먼저 선택하고 mode가 변경되면 이미지가 사라지는 이슈가 있네요! 대댓글 모드일때도 같은 이슈가 발생했어요.
그래서 detailsection에서

 const shouldPreserveImage =
      (prev.type === 'reset' && mode.action === 'create') ||
      (prev.action === 'create' && mode.type === 'reset') ||
      (prev.action === 'create' && mode.action === 'create');

    if (shouldPreserveImage) {
      return;
    }

이렇게 조건을 설정해서 위 케이스에서는 사용자가 작성 중인 이미지를 유지하도록 처리했습니다!

각 조건 설명:

  • reset → create: 이미지 선택 후 input 포커스 시 (댓글 작성 모드 진입 시)
  • create → reset: 대댓글 모드에서 backdrop 시
  • create → create: 댓글모드에서 대댓글 모드로 전환 시

dispatch({ type: 'COMMENT_CREATE' });
}
};

useClickOutside(
wrapperRef,
() => dispatch({ type: 'RESET' }),
Expand Down Expand Up @@ -137,10 +144,11 @@ const CommentInputBox = ({
<div className={styles.inputWrapper}>
<Input
key={focusKey}
autoFocus
autoFocus={mode.type === 'comment' || mode.type === 'reply'}
value={value}
onChange={onChange}
onKeyDown={handleKeyDown}
onFocus={handleFocus}
bgColor="white"
placeholder={PLACEHOLDER.COMMENT}
errorState={errorState}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@ const DetailSection = ({ postId }: DetailSectionProps) => {
const queryClient = useQueryClient();

useEffect(() => {
const isStillCreatingMode =
prevModeRef.current.action === 'create' && mode.action === 'create';
const typeChanged = prevModeRef.current.type !== mode.type;

const prev = prevModeRef.current;
prevModeRef.current = mode;

if (mode.type === 'comment' && mode.action === 'edit') {
Expand Down Expand Up @@ -72,7 +69,12 @@ const DetailSection = ({ postId }: DetailSectionProps) => {
return;
}

if (isStillCreatingMode && typeChanged) {
const shouldPreserveImage =
(prev.type === 'reset' && mode.action === 'create') ||
(prev.action === 'create' && mode.type === 'reset') ||
(prev.action === 'create' && mode.action === 'create');

if (shouldPreserveImage) {
return;
}

Expand Down Expand Up @@ -336,7 +338,6 @@ const DetailSection = ({ postId }: DetailSectionProps) => {
<>
<FeedContent postId={postId} />
<CommentInputBox
key={focusKey}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존에 key로 focusKey가 잡혀 있어서 mode가 변경되었을 때 key값이 변경되니 CommentInputBox도 같이 리렌더링되는 문제가 있었어요.
이에 따라 대댓글 입력창의 이미지가 깜빡이는 현상이 있어서 key를 제거했습니다.
여기에 애초에 key가 필요 없었을텐데 예전에 왜 넣었는지...

value={content}
onChange={handleChange}
errorState={isErrorState}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
Dispatch,
ReactNode,
useContext,
useEffect,
useMemo,
useReducer,
} from 'react';
Expand Down Expand Up @@ -36,14 +35,10 @@ export const InputModeContextProvider = ({
};

const [mode, dispatch] = useReducer(reducer, {
type: 'comment',
action: 'create',
postId,
type: 'reset',
action: 'reset',
} as const);

useEffect(() => {
dispatch({ type: 'RESET' });
}, [postId]);
const value = useMemo(() => ({ mode, dispatch }), [mode]);
return (
<InputModeContext.Provider value={value}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ export const createInputModeReducer = ({
action,
}: ComposeModeReducerType): InputBoxMode => {
switch (action.type) {
case 'COMMENT_CREATE':
return {
type: 'comment',
action: 'create',
postId,
} as const;
case 'COMMENT_EDIT':
return {
type: 'comment',
Expand Down Expand Up @@ -68,6 +74,6 @@ export const createInputModeReducer = ({

case 'RESET':
default:
return { type: 'comment', action: 'create', postId } as const;
return { type: 'reset', action: 'reset' } as const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}
};
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
import { useEffect, useRef, useState } from 'react';
import { useEffect, useState } from 'react';

import { InputBoxMode } from '@widgets/community/types/input-box-type';

import { LIMIT_SHORT_TEXT } from '@shared/constants/text-limits';

export const useControlledInputBox = (mode: InputBoxMode) => {
const [content, setContent] = useState(
'initialContent' in mode ? mode.initialContent : '',
);
const prevModeRef = useRef(mode);
const [content, setContent] = useState('');

useEffect(() => {
const isStillCreatingMode =
prevModeRef.current.action === 'create' && mode.action === 'create';
const typeChanged = prevModeRef.current.type !== mode.type;

prevModeRef.current = mode;
const initialContent = 'initialContent' in mode ? mode.initialContent : null;

if (isStillCreatingMode && typeChanged) {
return;
useEffect(() => {
if (initialContent !== null) {
setContent(initialContent);
}

setContent('initialContent' in mode ? mode.initialContent : '');
}, [mode]);
}, [initialContent]);

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const next = e.target.value;
Expand All @@ -32,7 +23,7 @@ export const useControlledInputBox = (mode: InputBoxMode) => {
};

const reset = () => {
setContent('initialContent' in mode ? mode.initialContent : '');
setContent('');
};

return { content, handleChange, reset };
Expand Down
2 changes: 2 additions & 0 deletions apps/client/src/widgets/community/types/input-box-type.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Image } from '@shared/types/type.ts';

export type InputBoxMode =
| { type: 'reset'; action: 'reset' }
| { type: 'comment'; action: 'create'; postId: string; images?: Image[] }
| {
type: 'comment';
Expand All @@ -24,6 +25,7 @@ export type InputBoxMode =
};

export type ReducerAction =
| { type: 'COMMENT_CREATE' }
| {
type: 'COMMENT_EDIT';
commentId: number;
Expand Down
Loading