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

Next.js 13 /app目录下使用FileReader报ReferenceError问题排查

问题原因及修复方案

核心问题

虽然你加了"use client"标记,但组件顶层的const fileReader = new FileReader()会在Next.js的服务端预渲染阶段被执行,而FileReader是浏览器专属API,服务端环境不存在这个对象,所以抛出ReferenceError: FileReader is not defined。

另外代码还有两个潜在问题:

  • readAsText是异步操作,不会直接返回读取的文本内容,需要通过监听事件获取结果
  • 代码中filename变量未定义,会导致后续路由跳转失败

修复后的代码

"use client";
import React, { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import useStore from "../app/store";

export default function FileUploader() {
  const [files, setFiles] = useState([]);
  const router = useRouter();
  const addFile = useStore((state) => state.addFile);

  const onFileSelect = (event) => {
    event.preventDefault();
    setFiles(event.target.files);
  };

  useEffect(() => {
    if (!files[0]) return;

    // 仅在浏览器环境创建FileReader实例
    const fileReader = new FileReader();
    const filename = files[0].name;

    // 通过onload事件获取异步读取的结果
    fileReader.onload = function(e) {
      const fileContent = e.target.result;
      addFile(fileContent);
      router.push(`/file/${filename}`);
    };

    // 开始读取文件
    fileReader.readAsText(files[0]);

    // 清理函数:避免组件卸载后触发事件
    return () => {
      fileReader.abort();
    };
  }, [files, addFile, router]);

  return (
    <input
      id="dropzone-file"
      type="file"
      className="fileInput"
      onChange={onFileSelect}
    />
  );
}

关键修改点

  • 把FileReader实例的创建移到useEffect内部,确保只在浏览器客户端执行
  • 使用fileReader.onload事件监听读取完成,获取文件内容
  • 补充filename变量的定义(从选中文件的name属性获取)
  • 添加清理函数,在组件卸载时终止文件读取,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:50:24