You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Formik在Next.js 14 App目录中无法正常工作的问题求助

Formik表单在Next.js 14中无法正常运行,出现类型错误

问题描述

严格按照Formik官方指南创建简单表单,但完全无法正常运行,报错信息如下:

错误信息

相关代码

package.json

{
  "name": "simple-form",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "formik": "^2.4.5",
    "next": "14.1.0",
    "react": "^18",
    "react-dom": "^18",
    "yup": "^1.3.3"
  },
  "devDependencies": {
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "eslint": "^8",
    "eslint-config-next": "14.1.0",
    "typescript": "^5"
  }
}

Formik组件代码(HomePage.tsx)

"use client";

import {Formik} from "formik";

interface MyFormValues {
    email: string;
    password: string;
}

export default function HomePage() {
    const initialValues: MyFormValues = { email: "", password: "" };

    return (
        <Formik
            initialValues={initialValues}
            onSubmit={(values) => console.log(values)}
        >
            {({ handleSubmit, handleChange, handleBlur, values }) => (
                <form onSubmit={handleSubmit}>
                    <input
                        type="email"
                        name = "email"
                        placeholder = "email"
                        onChange={handleChange}
                        onBlur={handleBlur}
                        value={values.email}
                    />
                    <input
                        type="password"
                        name = "password"
                        placeholder = "password"
                        onChange={handleChange}
                        onBlur={handleBlur}
                        value={values.password}
                    />
                    <button type="submit">Submit</button>
                </form>
            )}
        </Formik>
    );
}

解决方案

从错误信息来看,核心问题是Formik的类型定义与Next.js 14的App Router(use client模式)存在类型兼容问题,具体为FormikProps的泛型参数未正确传递,导致类型推断失败。

方案1:显式传递泛型参数

在Formik组件上明确指定MyFormValues作为泛型类型,帮助TypeScript正确推断所有相关props的类型:

<Formik<MyFormValues>
    initialValues={initialValues}
    onSubmit={(values) => console.log(values)}
>

方案2:改用useFormik钩子写法(更稳定)

组件式写法的类型兼容问题可以通过钩子写法规避,代码更清晰可控:

"use client";

import { useFormik } from "formik";

interface MyFormValues {
    email: string;
    password: string;
}

export default function HomePage() {
    const formik = useFormik<MyFormValues>({
        initialValues: { email: "", password: "" },
        onSubmit: (values) => {
            console.log(values);
        },
    });

    return (
        <form onSubmit={formik.handleSubmit}>
            <input
                type="email"
                name="email"
                placeholder="email"
                onChange={formik.handleChange}
                onBlur={formik.handleBlur}
                value={formik.values.email}
            />
            <input
                type="password"
                name="password"
                placeholder="password"
                onChange={formik.handleChange}
                onBlur={formik.handleBlur}
                value={formik.values.password}
            />
            <button type="submit">Submit</button>
        </form>
    );
}

方案3:添加完整表单验证(结合Yup)

如果需要实现验证功能,可补充Yup验证规则,示例如下:

"use client";

import { useFormik } from "formik";
import * as Yup from "yup";

interface MyFormValues {
    email: string;
    password: string;
}

export default function HomePage() {
    const formik = useFormik<MyFormValues>({
        initialValues: { email: "", password: "" },
        validationSchema: Yup.object({
            email: Yup.string().email("无效的邮箱格式").required("邮箱不能为空"),
            password: Yup.string().min(6, "密码至少6位").required("密码不能为空"),
        }),
        onSubmit: (values) => {
            console.log(values);
        },
    });

    return (
        <form onSubmit={formik.handleSubmit}>
            <div>
                <input
                    type="email"
                    name="email"
                    placeholder="email"
                    onChange={formik.handleChange}
                    onBlur={formik.handleBlur}
                    value={formik.values.email}
                />
                {formik.touched.email && formik.errors.email && (
                    <div style={{ color: "red" }}>{formik.errors.email}</div>
                )}
            </div>
            <div>
                <input
                    type="password"
                    name="password"
                    placeholder="password"
                    onChange={formik.handleChange}
                    onBlur={formik.handleBlur}
                    value={formik.values.password}
                />
                {formik.touched.password && formik.errors.password && (
                    <div style={{ color: "red" }}>{formik.errors.password}</div>
                )}
            </div>
            <button type="submit">Submit</button>
        </form>
    );
}

内容的提问来源于stack exchange,提问作者xtreebug

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 02:20:05