Skip to content

Commit

Permalink
๐Ÿ› fix: memo ์ถ”๊ฐ€ ๋ฐ ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌํ•˜์—ฌ re-rendering ์ตœ์†Œํ™” #42
Browse files Browse the repository at this point in the history
  • Loading branch information
froggy1014 committed Sep 1, 2024
1 parent 40be5d1 commit 65d1e8d
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ import { CREATE_FESTIVAL_SETTING } from "@/config";
import { CreateFestivalType } from "@/validations/CreateFestivalSchema";

const CreateFestivalFirstStep = () => {
const {
control,
formState: { dirtyFields },
} = useFormContext<CreateFestivalType>();
const { control } = useFormContext<CreateFestivalType>();

return (
<section className=" flex w-full flex-col gap-[32px]">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FC } from "react";
import { Controller, useFormContext, useWatch } from "react-hook-form";
import { FC, useCallback } from "react";
import { Controller, useFormContext } from "react-hook-form";

import {
FestivalCategory,
Expand All @@ -9,13 +9,14 @@ import {
AddressInput,
CategoryKeywordInput,
DescriptionInput,
DurationInput,
MoodKeywordInput,
TextInput,
TimeInput,
} from "@/components/core/Input";
import { CreateFestivalType } from "@/validations/CreateFestivalSchema";

import DurationFestivalInput from "./DurationFestivalInput";

interface Props {
moods: Array<FestivalMood>;
categories: Array<FestivalCategory>;
Expand All @@ -29,67 +30,57 @@ const CreateFestivalSecondStep: FC<Props> = ({ moods, categories }) => {
formState: { errors, submitCount },
} = useFormContext<CreateFestivalType>();

const startDate = useWatch({ control, name: "startDate" });
const endDate = useWatch({ control, name: "endDate" });
const time = useWatch({ control, name: "playtime" });

const handleCalendarConfirm = (start: string | null, end: string | null) => {
setValue("startDate", start ?? "", { shouldValidate: true });
setValue("endDate", end ?? "", { shouldValidate: true });
};

const handleAddress = (
address: string,
sido: string,
sigungu: string,
latitude: string,
longitude: string,
) => {
setValue("address", address ?? "", { shouldValidate: true });
setValue("sido", sido ?? "", { shouldValidate: true });
setValue("sigungu", sigungu ?? "", { shouldValidate: true });
setValue("latitude", latitude ?? "", { shouldValidate: true });
setValue("longitude", longitude ?? "", { shouldValidate: true });
setValue("address", address ?? "");
setValue("sido", sido ?? "");
setValue("sigungu", sigungu ?? "");
setValue("latitude", latitude ?? "");
setValue("longitude", longitude ?? "");
};

const handleTimeChange = (time: string) => {
setValue("playtime", time, { shouldValidate: true });
};
const handleGetError = useCallback(
(name: keyof CreateFestivalType) => {
if (submitCount < 2) {
return undefined;
}

const handleGetError = (name: keyof CreateFestivalType) => {
if (submitCount < 2) {
return undefined;
}

const errorMessage = errors[name]?.message ?? undefined;
const errorMessage = errors[name]?.message ?? undefined;

if (typeof errorMessage === "string") {
return errorMessage;
}
if (typeof errorMessage === "string") {
return errorMessage;
}

return undefined;
};
return undefined;
},
[errors],
);

return (
<section className="flex w-full flex-col gap-[18px]">
<DurationInput
label="ํŽ˜์Šคํ‹ฐ๋ฒŒ ๊ธฐ๊ฐ„"
start={startDate}
end={endDate}
error={handleGetError("startDate") || handleGetError("endDate")}
onConfirm={handleCalendarConfirm}
/>
<DurationFestivalInput handleGetError={handleGetError} />

<AddressInput
value={null}
onChange={handleAddress}
error={handleGetError("address")}
/>

<TimeInput
value={time}
onChange={handleTimeChange}
error={handleGetError("playtime")}
<Controller
control={control}
name="playtime"
render={({ field: { onChange, value } }) => (
<TimeInput
value={value}
onChange={onChange}
error={handleGetError("playtime")}
/>
)}
/>

<label className="text-subtitle-medium text-gray-scale-900">URL</label>
Expand Down
32 changes: 32 additions & 0 deletions src/app/(home)/festivals/new/_components/DurationFestivalInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { FC } from "react";
import { useFormContext, useWatch } from "react-hook-form";

import { DurationInput } from "@/components/core/Input";
import { CreateFestivalType } from "@/validations/CreateFestivalSchema";

interface Props {
handleGetError: (name: keyof CreateFestivalType) => string | undefined;
}

const DurationFestivalInput: FC<Props> = ({ handleGetError }) => {
const { control, setValue } = useFormContext<CreateFestivalType>();

const startDate = useWatch({ control, name: "startDate" });
const endDate = useWatch({ control, name: "endDate" });

const handleCalendarConfirm = (start: string | null, end: string | null) => {
setValue("startDate", start ?? "");
setValue("endDate", end ?? "");
};
return (
<DurationInput
label="ํŽ˜์Šคํ‹ฐ๋ฒŒ ๊ธฐ๊ฐ„"
start={startDate}
end={endDate}
error={handleGetError("startDate") || handleGetError("endDate")}
onConfirm={handleCalendarConfirm}
/>
);
};

export default DurationFestivalInput;
4 changes: 2 additions & 2 deletions src/components/core/Input/AddressInput/AddressInput.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, HtmlHTMLAttributes, useState } from "react";
import { FC, HtmlHTMLAttributes, memo, useState } from "react";
import { Address, useDaumPostcodePopup } from "react-daum-postcode";

import { ErrorIcon, PinLocationIcon } from "@/components/icons";
Expand Down Expand Up @@ -132,4 +132,4 @@ const AddressInput: FC<Props> = ({
);
};

export default AddressInput;
export default memo(AddressInput);
4 changes: 2 additions & 2 deletions src/components/core/Input/DurationInput/DurationInput.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ButtonHTMLAttributes, FC, useState } from "react";
import { ButtonHTMLAttributes, FC, memo, useState } from "react";

import { CalendarDialog } from "@/components/Dialog";
import { CalendarIcon, ErrorIcon } from "@/components/icons";
Expand Down Expand Up @@ -119,4 +119,4 @@ const DurationInput: FC<Props> = ({
);
};

export default DurationInput;
export default memo(DurationInput);
11 changes: 6 additions & 5 deletions src/components/core/Input/TimeInput/TimeInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
ChangeEvent,
ComponentPropsWithoutRef,
FC,
memo,
useEffect,
useRef,
useState,
Expand Down Expand Up @@ -47,12 +48,12 @@ const TimeInput: FC<Props> = ({
onChange(`${start ?? startTime} ~ ${end ?? endTime}`);
};

const handleStartTImeChange = (e: ChangeEvent<HTMLInputElement>) => {
const handleStartTimeChange = (e: ChangeEvent<HTMLInputElement>) => {
const time = e.target.value;
setStartTime(time);
handleOnChange(time);
};
const handleEndTImeChange = (e: ChangeEvent<HTMLInputElement>) => {
const handleEndTimeChange = (e: ChangeEvent<HTMLInputElement>) => {
const time = e.target.value;
setEndTime(time);
handleOnChange(undefined, time);
Expand Down Expand Up @@ -99,7 +100,7 @@ const TimeInput: FC<Props> = ({
!!startTime ? "text-primary-01" : "text-gray-400")
}
onClick={() => handleOpenPicker(startTimeRef)}
onChange={handleStartTImeChange}
onChange={handleStartTimeChange}
/>
<strong
className={cn(isBothSelected ? "text-primary-01" : "text-gray-400")}
Expand All @@ -116,7 +117,7 @@ const TimeInput: FC<Props> = ({
!!endTime ? "text-primary-01" : "text-gray-400",
)}
onClick={() => handleOpenPicker(endTimeRef)}
onChange={handleEndTImeChange}
onChange={handleEndTimeChange}
/>
</div>
</div>
Expand All @@ -137,4 +138,4 @@ const TimeInput: FC<Props> = ({
);
};

export default TimeInput;
export default memo(TimeInput);
10 changes: 2 additions & 8 deletions src/validations/CreateFestivalSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,8 @@ const CreateFestivalSchema = z.object({
instagramUrl: z.string().url(VALIDATION_ERROR_MESSAGES.url),
ticketLink: z.string().url(VALIDATION_ERROR_MESSAGES.url),
fee: z.string(),
categoryIds: z
.array(z.number())
.min(1, VALIDATION_ERROR_MESSAGES.min(1))
.max(2, VALIDATION_ERROR_MESSAGES.min(2)),
moodIds: z
.array(z.number())
.min(1, VALIDATION_ERROR_MESSAGES.min(1))
.max(2, VALIDATION_ERROR_MESSAGES.min(2)),
categoryIds: z.array(z.number()),
moodIds: z.array(z.number()),
tip: z.string(),
});

Expand Down

0 comments on commit 65d1e8d

Please sign in to comment.