Post 一个文件/一个文件的内容到 Formik 端点

Post a file /contents of a file to endpoint with Formik

我想创建一个允许用户上传文件(JSON 对象)然后 post 将该文件的内容上传到 api 的表单。

我想在 post 之前查看(现在只是在控制台日志中)我将要 post 的文件的内容。所以流程应该是这样的

我正在使用 useFormik 钩子,因为我在其他地方使用过它,并且发现它比 Formiks 的其他一些选项更直观,并且因为我认为它在我构建更多功能时会有用,所以可能会有这里有一些多余的代码行(例如 initialValues),但现在我只关注第一步 - 在 post 之前查看文件中的值。

看来我应该能够上传文件、读取文件内容、将文件内容存储在结果中,然后在最终 axios.post 中将该结果传递给 onSubmit 回调() 我会提出的要求。

但我不认为我理解这里的基本原理。

我应该使用新的 FormData 而不是 FileReader 吗?

我应该在 posting 之前阅读文件的内容吗?

这是我当前的代码:

import { useFormik } from 'formik';


export const MyUploadPerfectAssetForm = () => {

    const onChange = (event: any) => {

        const file = event.target.files[0];
        const reader = new FileReader();

        reader.onload = (e) => {
            // The file's text will be printed here
            console.log(e.target?.result)
            const result = e.target?.result;
            console.log("logging result from reader.onload " + result)
            return result;
        };

        //shows the files values properly
        reader.readAsText(file);


    }

        //redundant for now?
    const formik = useFormik({
        initialValues: {
            name: null,
            tags: null,
            type: null,
            s3URL: null,
            thumbnailImageURL: null,
        },

        onSubmit: (values, result) => {

            console.log("logging values" + JSON.stringify(values))
            alert(JSON.stringify(values, null, 2));


            console.log("logging values from onSubmit " + JSON.stringify(values))

            const uploadPerfectAsset = async (perfectAssetValues: any) => {

                //there will be an axios post request here, 

                console.log("upload perfect asset ran")
                console.log("testing uploadPerfectAsset with result from onChange file reader result" + JSON.stringify(perfectAssetValues))
            }

            uploadPerfectAsset(result)
        },


    });

    return (
        <div>
            <form onSubmit={formik.handleSubmit}>
                <div>
                    <input id="file"
                        name="test"
                        type="file"
                        onChange={onChange}></input>
                </div>
                <div>
                    <button type="submit">Submit</button></div>
            </form>
        </div >
    );
}

谢谢

你快完成了,伙计,需要做一些小的改变:

  • file 添加到 initialState
  • onChange函数移动到钩子useFormik()之后并添加formik.setFieldValue("file", file);设置值
  • 从函数 uploadPerfectAsset() 中删除参数 perfectAssetValues - 这是不必要的
export const MyUploadPerfectAssetForm = () => {
  const formik = useFormik({
    initialValues: {
      name: null,
      tags: null,
      type: null,
      s3URL: null,
      thumbnailImageURL: null,
      file: null
    },

    onSubmit: (values) => {
      console.log("logging values from onSubmit ", values);

      const uploadPerfectAsset = async () => {
        //there will be an axios post request here,

        console.log("upload perfect asset ran");
        console.log(
          "File info: ",
          JSON.stringify(
            {
              fileName: values.file.name,
              type: values.file.type,
              size: `${values.file.size} bytes`
            },
            null,
            2
          )
        );
      };

      uploadPerfectAsset();
    }
  });

  const onChange = (event) => {
    const file = event.target.files[0];
    formik.setFieldValue("file", file);
    const reader = new FileReader();

    // temporarily show file contentx
    reader.onload = (e) => {
      // The file's text will be printed here
      const result = e.target.result;
      console.log("logging result from reader.onload " + result);
      return result;
    };

    //shows the files values properly
    reader.readAsText(file);
  };

  return (
    <div>
      <form onSubmit={formik.handleSubmit}>
        <div>
          <input id="file" name="test" type="file" onChange={onChange}></input>
        </div>
        <div>
          <button type="submit">Submit</button>
        </div>
      </form>
    </div>
  );
};

Live demo