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

如何用Formik的useFormik钩子实现文件上传、预读内容并提交到接口

核心问题解答

1. FormData 和 FileReader 怎么选?

  • 如果你只需要把文件原封不动传给后端,后端接受multipart/form-data格式:直接用new FormData()把选中的File对象塞进去就行,不需要读内容。
  • 如果你需要提交前预览内容、前端校验JSON格式、修改内容再提交:必须用FileReader读取文件文本内容,刚好匹配你当前的需求场景。

2. 提交前需要先读取文件内容吗?

你要预览打印内容,就必须提前读。如果不需要预览,只是纯上传文件,就不用读。


代码修改方案

你当前的核心问题是:FileReader.onload是异步回调,你在回调里return的result无法被外部获取,也没有存到Formik的状态里,所以onSubmit里取不到文件内容。
修改后代码如下:

import { useFormik } from 'formik';
import axios from 'axios';

export const MyUploadPerfectAssetForm = () => {
  const formik = useFormik({
    initialValues: {
      name: null,
      tags: null,
      type: null,
      s3URL: null,
      thumbnailImageURL: null,
      // 新增字段存读取到的JSON内容和原始文件
      jsonContent: null,
      rawFile: null
    },
    onSubmit: async (values) => {
      console.log('待提交的JSON内容:', values.jsonContent);
      
      // 场景1:后端要求直接传JSON对象作为请求体
      try {
        // 把JSON字符串转成对象(如果读取时已经转了这里可以省略)
        const payload = JSON.parse(values.jsonContent);
        await axios.post('你的API端点地址', payload);
        alert('提交成功');
      } catch (err) {
        console.error('提交失败', err);
        alert('提交失败,请检查JSON格式或网络');
      }

      // 场景2:后端要求传multipart/form-data格式的文件
      // const formData = new FormData();
      // formData.append('file', values.rawFile);
      // await axios.post('你的API端点地址', formData, {
      //   headers: { 'Content-Type': 'multipart/form-data' }
      // });
    },
  });

  const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (!file) return;

    // 存原始文件到formik状态,后续需要传FormData的时候用
    formik.setFieldValue('rawFile', file);

    const reader = new FileReader();
    reader.onload = (e) => {
      const fileContent = e.target?.result as string;
      // 选中后直接打印预览内容,满足你提交前查看的需求
      console.log('选中的JSON文件内容:', fileContent);
      // 把内容存到formik状态,提交的时候直接取
      formik.setFieldValue('jsonContent', fileContent);

      // 可选:提前校验JSON格式,选中即校验不用等提交报错
      try {
        JSON.parse(fileContent);
      } catch (err) {
        alert('选择的文件不是合法的JSON格式,请重新选择');
        // 清空错误的文件和内容
        formik.setFieldValue('rawFile', null);
        formik.setFieldValue('jsonContent', null);
        event.target.value = '';
      }
    };
    reader.readAsText(file);
  }

  return (
    <div>
      <form onSubmit={formik.handleSubmit}>
        <div>
          <input 
            id="file"
            name="test"
            type="file"
            accept=".json" // 限制只能选JSON文件,减少格式错误
            onChange={handleFileChange}
          />
        </div>
        <div>
          {/* 可选:没有选中合法文件的时候禁用提交按钮 */}
          <button type="submit" disabled={!formik.values.jsonContent}>
            提交
          </button>
        </div>
      </form>
    </div >
  );
}

补充说明

  • 给文件选择框加了accept=".json"限制用户只能选JSON文件,减少误操作
  • 加了可选的JSON格式校验逻辑,可根据自己的需求决定要不要保留
  • 两种常见的提交场景都加了注释,你根据后端接口要求选择对应代码即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:06:02