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

Apify-Client在React项目中运行报错问题求助

问题原因

  1. 导出逻辑错误:你的apify.js中把导出语句注释了,即使解开注释,export default getItems()的写法也是错误的——你导出的是函数执行后的返回值(Promise对象),而非函数本身,导致React组件导入的getItems不是可调用的函数。
  2. Node专属API不兼容浏览器环境:apify.js中的require('dotenv').config()配置、__dirname变量都是Node.js运行环境下的专属能力,React代码最终运行在浏览器中,不存在这些API,直接运行会抛出未定义错误。
  3. 多余的全局执行逻辑:apify.js末尾的getItems()会导致该模块被导入时就自动执行一次函数,不符合你在useEffect中按需调用的预期。
  4. 可选:你使用的apify-client@1.2.4默认是为Node环境构建的,部分依赖可能不兼容浏览器环境。

解决步骤

1. 重写apify.js文件

移除所有Node专属代码,修正导出逻辑:

import { ApifyClient } from 'apify-client';

const client = new ApifyClient({
  token: process.env.REACT_APP_API_TOKEN,
});

const input = {};

const getItems = async () => {
  // Run the actor and wait for it to finish
  const run = await client.actor('petrpatek/covid-19-aggregator').call(input);

  // Fetch and print actor results from the run's dataset (if any)
  console.log('Results from dataset');
  const { items } = await client.dataset(run.defaultDatasetId).listItems();
  items.forEach((item) => {
    console.dir(item);
  });

  return items;
};

// 正确导出函数本身,不要加执行括号
export default getItems;

同时确认你的.env文件放在项目根目录(与package.json同级),变量名格式符合React要求,以REACT_APP_开头:

REACT_APP_API_TOKEN=你的Apify接口令牌

2. (可选)替换为原生fetch调用,避免依赖兼容问题

如果修改后仍报apify-client相关错误,可以直接用浏览器原生fetch调用接口,不需要引入额外依赖,兼容性更好:

const API_TOKEN = process.env.REACT_APP_API_TOKEN;
const ACTOR_ID = 'petrpatek/covid-19-aggregator';

const getItems = async () => {
  // 发起actor运行请求
  const runRes = await fetch(`https://api.apify.com/v2/acts/${ACTOR_ID}/runs?token=${API_TOKEN}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({})
  });
  const runData = await runRes.json();
  const runId = runData.data.id;

  // 轮询等待任务运行完成
  let runStatus;
  do {
    await new Promise(resolve => setTimeout(resolve, 1000));
    const statusRes = await fetch(`https://api.apify.com/v2/acts/runs/${runId}?token=${API_TOKEN}`);
    const statusData = await statusRes.json();
    runStatus = statusData.data.status;
  } while (runStatus === 'RUNNING' || runStatus === 'READY');

  // 拉取运行结果
  const itemsRes = await fetch(`https://api.apify.com/v2/datasets/${runData.data.defaultDatasetId}/items?token=${API_TOKEN}`);
  const items = await itemsRes.json();
  
  console.log('Results from dataset', items);
  return items;
};

export default getItems;

3. 组件中适配异步逻辑,存储返回数据

如果需要在页面渲染接口返回的内容,可以用useState存储数据,修改组件代码如下:

import { useEffect, useState } from 'react';
import CountryCard from '../components/countryCard';
import Header from '../components/header';
import getItems from '../APIs/apify';

const AllCountriesPage = () => {
  const [countryList, setCountryList] = useState([]);

  useEffect(() => {
    // 处理异步调用
    const fetchData = async () => {
      const data = await getItems();
      setCountryList(data);
    };
    fetchData();
  }, []);

  return (
    <div className="allCountriesPage">
      <Header />
      <CountryCard className="bannerCountry" />
      <p className="allCountriesText">All countries</p>
      <div className="allCountriesContainer">
        {/* 遍历渲染国家卡片 */}
        {countryList.map((country, index) => (
          <CountryCard key={index} data={country} />
        ))}
      </div>
    </div>
  );
};

export default AllCountriesPage;

注意事项

直接将API令牌放在前端代码中会导致令牌泄露,任何人都可以通过前端代码拿到你的令牌调用Apify接口、消耗你的账户配额,生产环境建议增加后端代理层,前端只请求自己的后端接口,由后端携带令牌请求Apify接口返回数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 07:24:02