• 카테고리

    질문 & 답변
  • 세부 분야

    프론트엔드

  • 해결 여부

    해결됨

No overload matches this call.

24.03.11 18:13 작성 조회수 240

0

z-com\src\app\(beforeLogin)\_component\SignupModal.tsx

파일에서 useFormState(OnSubmit, {message: null }); 해당 부분에서


Type error:No overload matches this call.
Overload 1 of 2, '(action: (state: { message: string; } | undefined) => { message: string; } | Promise<{ message: string; } | undefined> | undefined, initialState: { message: string; } | undefined, permalink?: string | undefined): [state: ...]', gave the following error.
Argument of type '(prevState: any, formData: FormData) => Promise<{ message: string; } | undefined>' is not assignable to parameter of type '(state: { message: string; } | undefined) => { message: string; } | Promise<{ message: string; } | undefined> | undefined'.
Target signature provides too few arguments. Expected 2 or more, but got 1.
Overload 2 of 2, '(action: (state: { message: string; } | undefined, payload: FormData) => { message: string; } | Promise<{ message: string; } | undefined> | undefined, initialState: { message: string; } | undefined, permalink?: string | undefined): [state: ...]', gave the following error.
Type 'null' is not assignable to type 'string'.ts(2769)

에러가 발생합니다.

제로초님 github 파일 3-2에 있는 부분을 복붙해서 하고 있는데 에러가 발생했습니다. 타이핑 에러는 아닌 것 같습니다.

찾아보니 함수에 들어오는 매개변수의 타입이 예상한 타입과 일치하지 않을 때 발생한다고 하여서

message의 type을 any로 바꿔보아도 에러가 납니다 ..

React 버전은 18버전이고 nextjs 는 14.0.4 버전입니다.

어떤 부분을 수정해야 할지 모르겠습니다...

 

 

답변 1

답변을 작성해보세요.

0

코드 보여주세요. null 관련 에러라서 string을 string | null 로 수정하면 될 것 같긴 합니다.

jun Kim님의 프로필

jun Kim

질문자

2024.03.12

"use client";

import style from "./signup.module.css";
import onSubmit from "../_lib/signup";
import BackButton from "@/app/(beforeLogin)/_component/backbutton";
import { useFormState, useFormStatus } from "react-dom";

function showMessage(messasge: string) {
  if (messasge === "no_id") {
    return "아이디를 입력하세요.";
  }
  if (messasge === "no_name") {
    return "닉네임을 입력하세요.";
  }
  if (messasge === "no_password") {
    return "비밀번호를 입력하세요.";
  }
  if (messasge === "no_image") {
    return "이미지를 업로드하세요.";
  }
  if (messasge === "user_exists") {
    return "이미 사용 중인 아이디입니다.";
  }
  return "";
}

export default function SignupModal() {
  const [state, formAction] = useFormState(onSubmit, { message: null });
  const { pending } = useFormStatus();

  return (
    <>
      <div className={style.modalBackground}>
        <div className={style.modal}>
          <div className={style.modalHeader}>
            <BackButton />
            <div>계정을 생성하세요.</div>
          </div>
          <form action={formAction}>
            <div className={style.modalBody}>
              <div className={style.inputDiv}>
                <label className={style.inputLabel} htmlFor="id">
                  아이디
                </label>
                <input
                  id="id"
                  name="id"
                  className={style.input}
                  type="text"
                  placeholder=""
                  required
                />
              </div>
              <div className={style.inputDiv}>
                <label className={style.inputLabel} htmlFor="name">
                  닉네임
                </label>
                <input
                  id="name"
                  name="name"
                  className={style.input}
                  type="text"
                  placeholder=""
                  required
                />
              </div>
              <div className={style.inputDiv}>
                <label className={style.inputLabel} htmlFor="password">
                  비밀번호
                </label>
                <input
                  id="password"
                  name="password"
                  className={style.input}
                  type="password"
                  placeholder=""
                  required
                />
              </div>
              <div className={style.inputDiv}>
                <label className={style.inputLabel} htmlFor="image">
                  프로필
                </label>
                <input
                  id="image"
                  name="image"
                  required
                  className={style.input}
                  type="file"
                  accept="image/*"
                />
              </div>
            </div>
            <div className={style.modalFooter}>
              <button
                type="submit"
                className={style.actionButton}
                disabled={pending}
              >
                가입하기
              </button>
              <div className={style.error}>{showMessage(state?.message)}</div>
            </div>
          </form>
        </div>
      </div>
    </>
  );
}

이게 /src/app/(beforeLogin)/_component/SignupModal.tsx 전체 코드입니다.

jun Kim님의 프로필

jun Kim

질문자

2024.03.12

"use server";

import { redirect } from "next/navigation";
import { signIn } from "@/auth";

export default async (
  prevState: { message: string | null },
  formData: FormData
) => {
  if (!formData.get("id") || !(formData.get("id") as string)?.trim()) {
    return { message: "no_id" };
  }
  if (!formData.get("name") || !(formData.get("name") as string)?.trim()) {
    return { message: "no_name" };
  }
  if (
    !formData.get("password") ||
    !(formData.get("password") as string)?.trim()
  ) {
    return { message: "no_password" };
  }
  if (!formData.get("image")) {
    return { message: "no_image" };
  }
  let shouldRedirect = false;
  try {
    const response = await fetch(
      `${process.env.NEXT_PUBLIC_BASE_URL}/api/users`,
      {
        method: "post",
        body: formData,
        credentials: "include",
      }
    );
    console.log(response.status);
    if (response.status === 403) {
      return { message: "user_exists" };
    }
    console.log(await response.json());
    shouldRedirect = true;
    await signIn("credentials", {
      username: formData.get("id"),
      password: formData.get("password"),
      redirect: false,
    });
  } catch (err) {
    console.error(err);
    return;
  }

  if (shouldRedirect) {
    redirect("/home"); // try/catch문 안에서 X
  }
};

위의 코드는 signup.ts입니다.

path는 /src/app/(beforeLogin)/_lib/signup.ts입니다.

 

"클라이언트 컴포넌트에서 Server Actions 사용하기 "

제로초님이 해당 강의 4: 10초 정도에 singup.ts 파일의 6번째 줄인

export default async ( prevState: { message: string | null }, formData: FormData )

이 부분에서 prevState: { message: string | null } 이 부분을 prevState : any로 고치셨는데 SingupModal.ts 파일에서 no overload matches this call 에러가 사라졌습니다. 근데 저는 따라했는데 사라지지 않아서 질문 남깁니다.

 

현재는 제가 처음에 질문에 올린 에러 메세지가 다르게 뜹니다.

No overload matches this call.
Overload 1 of 2, '(action: (state: { message: string; } | undefined) => { message: string; } | Promise<{ message: string; } | undefined> | undefined, initialState: { message: string; } | undefined, permalink?: string | undefined): [state: ...]', gave the following error.
Argument of type '(prevState: { message: string | null;}, formData: FormData) => Promise<{ message: string; } | undefined>' is not assignable to parameter of type '(state: { message: string; } | undefined) => { message: string; } | Promise<{ message: string; } | undefined> | undefined'.
Target signature provides too few arguments. Expected 2 or more, but got 1.
Overload 2 of 2, '(action: (state: { message: string; } | undefined, payload: FormData) => { message: string; } | Promise<{ message: string; } | undefined> | undefined, initialState: { message: string; } | undefined, permalink?: string | undefined): [state: ...]', gave the following error.
Argument of type '(prevState: { message: string | null;}, formData: FormData) => Promise<{ message: string; } | undefined>' is not assignable to parameter of type '(state: { message: string; } | undefined, payload: FormData) => { message: string; } | Promise<{ message: string; } | undefined> | undefined'.
Types of parameters 'prevState' and 'state' are incompatible.
Type '{ message: string; } | undefined' is not assignable to type '{ message: string | null; }'.
Type 'undefined' is not assignable to type '{ message: string | null; }' .ts(2769)

 


이렇게 뜨고 있습니다.signupModal.png

jun Kim님의 프로필

jun Kim

질문자

2024.03.12

늦은 시간에 정말 감사합니다!!!