개발일기장/Next.js로 리팩토링하기

[D'art] Next.js로 리팩토링하기 4일차

고래강이 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 전달까지 구현해보자.