ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [D'art] Next.js로 리팩토링하기 4일차
    개발일기장/Next.js로 리팩토링하기 2025. 2. 3. 14:33
    기록물 작성이 제대로 되지 않는 것 같다 순차적으로 하나씩 해결을 해나가야하는데 자꾸 이거저거 손이 뻗다보니 중간에 잘 작성을 안하게 되는 것 같다. 4일차부터는 이러한 습관부터 먼저 들여서 하나씩 해결해서 프로젝트를 완성해보자.

     


    📦 목표

    1️⃣ Signup Page 완성하기

    App router를 통해서 경로를 어떻게 설정해야할지에 대한 고민을 많이 해야할 것 같고 기타 input의 state관리나 2단계로 나뉘는 과정 중 순서를 보장할 수 있는 방법도 기존의 방법에서 더 나은 방법이나 SSR을 어떻게 잘 적용할 수 있는지 고려해보자. 알림창도 하나 있으면 좋을 것 같으니깐 Page가 완성되면 Alert을 하나 만들어보자.

     

    - UI 만들기

     

    Header의 위치를 어떻게 해야할까?

    page가 Agree와 Info 2개의 2단계로 나뉘어서 각 단계별로 header의 1, 2이 숫자만 바뀌는데 이거를 SSR로 처리를 하는 방법은 없을까?

     

    2️⃣ UnControlled Form 적용해보기

    React hook form을 적용하려던 와중 옛날에 공부했던 내용을 토대로 적용을 해보려고 한다.
    출처: React controlled Form vs uncontrolled Form

     

    기존에 inputField는 react-hook-form에 의존적인 코드를 가지고 있었다 register를 필수 props로 받고, error를 비롯한 value값 또한 props로 받기에 uncontrolled 방식을 적용하려 코드를 수정해보았다.

    import useInputOptions from "@/hooks/useInputOptions";
    import BlindIcon from "@/ui/icon/blind";
    import clsx from "clsx";
    
    interface InputFieldProps {
      label: string;
      value: string;
      disabled?: boolean;
    }
    
    const InputField = ({ label, value, disabled = false }: InputFieldProps) => {
      const {
        isBlinded,
        isFocused,
        toggleBlinded,
        labelFocusedNBlur,
        inputOptions,
      } = useInputOptions({ label });
    
      return (
        <div className="relative mt-10 flex w-full flex-row items-center gap-5">
          <label
            className={clsx(
              isFocused ? "top-[-15px] text-sm" : "text-xl",
              "absolute top-0 text-cwhite transition-all duration-300",
            )}
            htmlFor={value}
          >
            {label}
          </label>
          <input
            id={value}
            {...inputOptions}
            {...labelFocusedNBlur}
            autoFocus={value === "email" || value === "nickname" ? true : false}
            disabled={disabled}
            maxLength={40}
            className={clsx(
              "mt-3 w-full rounded-sm border-b border-white p-2 pt-0 text-lg text-white",
              disabled ? "bg-cgray-500" : "",
            )}
          />
          {label.includes("password") && (
            <BlindIcon
              onClick={toggleBlinded}
              color={isBlinded ? "white" : "green"}
              styles="absolute right-0 top-1/2 -translate-y-1/2"
            />
          )}
          <button className="h-10 w-20 border text-xs">버튼</button>
        </div>
      );
    };
    
    export default InputField;​

    아직 value를 어떻게 업데이트하고 validation은 어떻게 할지 또한 button에 대해 modal을 띄워서 value를 변경하는 등 기존의 기능을 구현 못한 부분이 있지만 UI를 어느정도 구현해 놓았으며 특히 비즈니스로직을 분리하는 과정에 신경을 많이 썻으며 현재는 label값만 부여를 하면 되기에 의존도를 많이 줄인 상태로 구현할 수 있었다.

     

    -> 이후 방향성

    1. validation을 어떻게 할지에 대해서 고민하고 적용을해보자
    2. 스타일링을 좀 더 정립해서 convention을 가진 스타일링을 적용해보자
    3. form과 연계해서 server action까지 적용해서 formData 전달까지 구현해보자.

    댓글

Designed by Tistory.