Skip to content

Commit

Permalink
refactor: 방 생성, 관리 페이지 렌더링 최적화 (#508)
Browse files Browse the repository at this point in the history
* refactor: BirdStep 렌더링 최적화

* refactor: TimeStep 렌더링 최적화

* refactor: RoutineStep 렌더링 최적화

* fix: BirdCard 이미지 로딩중에 UI 흔들리는 현상 수정

* refactor: RoomTab 렌더링 최적화

* refactor: StepTemplate 작성

* refactor: 방 수정 페이지에서 Fragment 제거
  • Loading branch information
bbearcookie authored Mar 5, 2024
1 parent 94e1311 commit 2760f47
Show file tree
Hide file tree
Showing 13 changed files with 136 additions and 115 deletions.
9 changes: 4 additions & 5 deletions src/domain/RoomForm/components/Routines.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback } from 'react';
import { useFieldArray, useFormContext } from 'react-hook-form';
import { useFieldArray, useFormContext, useWatch } from 'react-hook-form';
import { InnerTextInput } from '@/shared/Input';
import { Icon } from '@/shared/Icon';
import { FORM_LITERAL } from '../constants/literals';
Expand All @@ -8,13 +8,10 @@ import { errorStyle, iconButtonStyle } from '../constants/styles';
const Routines = () => {
const {
register,
watch,
control,
formState: { errors }
} = useFormContext<{ routines: Array<{ value: string }> }>();

const watchRoutines = watch('routines');

const {
append,
fields: routines,
Expand All @@ -24,6 +21,8 @@ const Routines = () => {
control
});

const watchRoutines = useWatch({ name: 'routines', control });

const handleAppendRoutine = useCallback(() => {
if (routines.length >= FORM_LITERAL.routines.max.value) {
return;
Expand Down Expand Up @@ -52,7 +51,7 @@ const Routines = () => {
wrapperStyle="w-full"
textStyle="text-xs text-gray-400"
text={
watchRoutines[idx].value.length.toString() +
watchRoutines[idx]?.value.length.toString() +
' / ' +
FORM_LITERAL.routines.item.max.value
}
Expand Down
8 changes: 4 additions & 4 deletions src/domain/RoomForm/components/UserCount.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { useCallback } from 'react';
import { useFormContext } from 'react-hook-form';
import { useFormContext, useWatch } from 'react-hook-form';
import { Icon } from '@/shared/Icon';
import { iconButtonStyle, errorStyle } from '../constants/styles';
import { FORM_LITERAL } from '../constants/literals';

const UserCount = () => {
const {
setValue,
watch,
formState: { errors }
formState: { errors },
control
} = useFormContext<{ userCount: number }>();

const watchUserCount = watch('userCount');
const watchUserCount = useWatch({ name: 'userCount', control });

const handleSetUserCount = useCallback(
(count: number) => {
Expand Down
2 changes: 1 addition & 1 deletion src/domain/RoomNew/components/BirdCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const BirdCard = ({
)}
onClick={handleSelect}
>
<div className={clsx('w-24 rounded-full', BIRD[type].bg)}>
<div className={clsx('h-20 w-20 rounded-full', BIRD[type].bg)}>
<img
src={BIRD[type].image}
className="p-4"
Expand Down
6 changes: 3 additions & 3 deletions src/domain/RoomNew/components/BirdCardSection.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Suspense } from 'react';
import { useSuspenseQuery } from '@tanstack/react-query';
import { useFormContext } from 'react-hook-form';
import { useFormContext, useWatch } from 'react-hook-form';
import { roomOptions } from '@/core/api/options';
import { QueryErrorBoundary, NetworkFallback } from '@/shared/ErrorBoundary';
import {
Expand All @@ -13,9 +13,9 @@ import BirdCard from './BirdCard';
import BirdCardFallback from './BirdCardFallback';

const BirdCardSectionComponent = () => {
const { setValue, watch } = useFormContext<Inputs>();
const { setValue, control } = useFormContext<Inputs>();

const watchType = watch('roomType');
const watchType = useWatch({ name: 'roomType', control });

const { data: roomCount } = useSuspenseQuery({
...roomOptions.myJoin(),
Expand Down
21 changes: 21 additions & 0 deletions src/domain/RoomNew/components/StepTemplate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import { motion } from 'framer-motion';

interface StepTemplateProps {
children: React.ReactNode;
}

const StepTemplate = ({ children }: StepTemplateProps) => {
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ ease: 'easeInOut', duration: 0.25 }}
>
{children}
</motion.div>
);
};

export default StepTemplate;
5 changes: 3 additions & 2 deletions src/domain/RoomNew/steps/BirdStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import {
} from '../constants/styles';
import { Inputs } from '../hooks/useRoomForm';
import BirdCardSection from '../components/BirdCardSection';
import StepTemplate from '../components/StepTemplate';

const BirdStep = () => {
const {
formState: { errors }
} = useFormContext<Inputs>();

return (
<>
<StepTemplate>
<h1 className={headingStyle}>
<strong>어떤 새를</strong>
<p>키우는 방일까요?</p>
Expand All @@ -30,7 +31,7 @@ const BirdStep = () => {
{errors.roomType && (
<p className={errorStyle}>{errors.roomType.message}</p>
)}
</>
</StepTemplate>
);
};

Expand Down
5 changes: 3 additions & 2 deletions src/domain/RoomNew/steps/PasswordStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import clsx from 'clsx';
import { FORM_LITERAL } from '@/domain/RoomForm/constants/literals';
import { Password } from '@/domain/RoomForm';
import { headingStyle, descriptionStyle } from '../constants/styles';
import StepTemplate from '../components/StepTemplate';

const PasswordStep = () => {
const min = FORM_LITERAL.password.min.value;
const max = FORM_LITERAL.password.max.value;

return (
<>
<StepTemplate>
<h1 className={headingStyle}>
<strong>마지막 !</strong>
<p>
Expand All @@ -21,7 +22,7 @@ const PasswordStep = () => {
</p>

<Password placeholder="비워두시면 공개방이 됩니다" />
</>
</StepTemplate>
);
};

Expand Down
5 changes: 3 additions & 2 deletions src/domain/RoomNew/steps/RoutineStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Routines, UserCount } from '@/domain/RoomForm';
import { errorStyle } from '../constants/styles';
import { Inputs } from '../hooks/useRoomForm';
import { descriptionStyle } from '../constants/styles';
import StepTemplate from '../components/StepTemplate';

const RoutineStep = () => {
const {
Expand All @@ -13,7 +14,7 @@ const RoutineStep = () => {
} = useFormContext<Inputs>();

return (
<>
<StepTemplate>
<section className={sectionStyle}>
<h2 className={headingStyle}>
<b>방 이름</b>을 지어주세요.
Expand All @@ -39,7 +40,7 @@ const RoutineStep = () => {
</h2>
<UserCount />
</section>
</>
</StepTemplate>
);
};

Expand Down
6 changes: 3 additions & 3 deletions src/domain/RoomNew/steps/SummaryStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { formatHourString } from '@/domain/TimePicker/utils/hour';
import { BIRD } from '@/domain/RoomForm/constants/literals';
import { headingStyle, descriptionStyle } from '../constants/styles';
import { Inputs } from '../hooks/useRoomForm';
import StepTemplate from '../components/StepTemplate';

interface Info {
icon: keyof typeof iconMap;
Expand All @@ -14,7 +15,6 @@ interface Info {

const SummaryStep = () => {
const { getValues } = useFormContext<Inputs>();

const routines = getValues('routines');

const infos: Info[] = [
Expand Down Expand Up @@ -46,7 +46,7 @@ const SummaryStep = () => {
];

return (
<>
<StepTemplate>
<h1 className={headingStyle}>
<strong>준비 끝 !</strong>
</h1>
Expand Down Expand Up @@ -76,7 +76,7 @@ const SummaryStep = () => {
</li>
))}
</ul>
</>
</StepTemplate>
);
};

Expand Down
27 changes: 16 additions & 11 deletions src/domain/RoomNew/steps/TimeStep.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useFormContext } from 'react-hook-form';
import { Controller, useFormContext, useWatch } from 'react-hook-form';
import { formatHourString } from '@/domain/TimePicker/utils/hour';
import { TIME_RANGE } from '@/domain/RoomForm/constants/literals';
import { TimePicker } from '@/domain/TimePicker';
Expand All @@ -8,19 +8,18 @@ import {
errorStyle
} from '../constants/styles';
import { Inputs } from '../hooks/useRoomForm';
import StepTemplate from '../components/StepTemplate';

const TimeStep = () => {
const {
setValue,
watch,
control,
formState: { errors }
} = useFormContext<Inputs>();

const watchRoomType = watch('roomType');
const watchCertifyTime = watch('certifyTime');
const watchRoomType = useWatch({ name: 'roomType', control });

return (
<>
<StepTemplate>
<h1 className={headingStyle}>
<strong>언제 </strong>
인증할까요?
Expand All @@ -32,18 +31,24 @@ const TimeStep = () => {

<section className="mt-10 flex w-full flex-col items-center gap-6">
<div>{formatHourString(TIME_RANGE[watchRoomType][0])}</div>
<TimePicker
range={TIME_RANGE[watchRoomType]}
initialTime={watchCertifyTime}
onChangeTime={(time) => setValue('certifyTime', time)}
<Controller
name="certifyTime"
control={control}
render={({ field }) => (
<TimePicker
range={TIME_RANGE[watchRoomType]}
initialTime={field.value}
onChangeTime={field.onChange}
/>
)}
/>
<div>{formatHourString(TIME_RANGE[watchRoomType][1])}</div>
</section>

{errors.certifyTime && (
<p className={errorStyle}>{errors.certifyTime.message}</p>
)}
</>
</StepTemplate>
);
};

Expand Down
62 changes: 33 additions & 29 deletions src/domain/RoomSetting/tabs/RoomTab.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useSuspenseQuery } from '@tanstack/react-query';
import { FormProvider } from 'react-hook-form';
import { Controller, FormProvider } from 'react-hook-form';
import ReactTextareaAutosize from 'react-textarea-autosize';
import clsx from 'clsx';
import { roomOptions } from '@/core/api/options';
Expand Down Expand Up @@ -44,12 +44,10 @@ const RoomTab = ({ roomId }: RoomTabProps) => {
const {
register,
setValue,
watch,
control,
formState: { errors }
} = form;

const watchAnnouncement = watch('announcement');

return (
<FormProvider {...form}>
<form onSubmit={handleSubmit}>
Expand All @@ -70,32 +68,38 @@ const RoomTab = ({ roomId }: RoomTabProps) => {
)}
</section>

<section className={sectionStyle}>
<label
className={clsx(labelStyle, 'flex justify-between')}
htmlFor="announcement"
>
<b>공지사항</b>
<p className="text-xs text-gray-400">
{watchAnnouncement.length} / {FORM_LITERAL.announcement.max.value}
</p>
</label>
<ReactTextareaAutosize
className={clsx(
'w-full resize-none p-3 text-sm',
'rounded-lg border border-gray-300 shadow-sm placeholder:text-gray-400',
'focus:border-light-point focus:outline-none focus:ring-1 focus:ring-light-point',
'dark:bg-dark-sub dark:focus:border-dark-point dark:focus:ring-dark-point'
)}
minRows={3}
maxLength={FORM_LITERAL.announcement.max.value}
id="announcement"
{...register('announcement')}
/>
{errors.announcement && (
<p className={errorStyle}>{errors.announcement?.message}</p>
<Controller
name="announcement"
control={control}
render={({ field }) => (
<section className={sectionStyle}>
<label
className={clsx(labelStyle, 'flex justify-between')}
htmlFor="announcement"
>
<b>공지사항</b>
<p className="text-xs text-gray-400">
{field.value.length} / {FORM_LITERAL.announcement.max.value}
</p>
</label>
<ReactTextareaAutosize
className={clsx(
'w-full resize-none p-3 text-sm',
'rounded-lg border border-gray-300 shadow-sm placeholder:text-gray-400',
'focus:border-light-point focus:outline-none focus:ring-1 focus:ring-light-point',
'dark:bg-dark-sub dark:focus:border-dark-point dark:focus:ring-dark-point'
)}
minRows={3}
maxLength={FORM_LITERAL.announcement.max.value}
id="announcement"
{...field}
/>
{errors.announcement && (
<p className={errorStyle}>{errors.announcement?.message}</p>
)}
</section>
)}
</section>
/>

<section className={sectionStyle}>
<label
Expand Down
Loading

0 comments on commit 2760f47

Please sign in to comment.