【问题标题】:Issue with useEffect dependency arrayuseEffect 依赖数组的问题
【发布时间】:2021-10-11 17:44:49
【问题描述】:

我的项目正在使用 useState 和 useEffect 挂钩从 API 获取数据。该请求在我的本地主机上正常工作和呈现,但我收到以下警告:

React Hook useEffect 缺少一个依赖项:'fetchData'。要么包含它,要么移除依赖数组。

警告阻止我部署我的项目。我已经尝试将“fetchData”添加到数组以及完全删除数组。两者都会导致错误。

将 'fetchData' 添加到数组会导致另一个警告:

'fetchData' 函数使 useEffect Hook(第 31 行)的依赖关系在每次渲染时都发生变化。将它移到 useEffect 回调中。或者,将 'fetchData' 的定义包装在它自己的 useCallback() Hook 中。

删除数组会导致此控制台错误:

CORS 策略阻止了从源“http://localhost:3000”获取的访问权限:请求的资源上不存在“Access-Control-Allow-Origin”标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

我只需要在加载时渲染一次状态。这是我的代码:

export function Product({Inventory_ID, Cost}) {
  const [ data, setData ] = useState("");
  const [ centers, setCenters ] = useState([]);

  const fetchData = async () => {
    try {
      const response = await fetch(`${API_ENDPOINT}${Inventory_ID}`, REQUEST_OPTIONS);
      const data = await response.json();
      setData(data);

      const centers = await data.fulfillable_quantity_by_fulfillment_center;
      setCenters(centers);
    } catch (e) {
      console.error(e);
    }
  }

  useEffect(() => {
    fetchData();
  }, []);

  // Currency formatter
  const formatter = new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
    maximumFractionDigits: 0,
  })

  return (
    <div className="card">
      <h2>{data.name}</h2>
      <h3>Total Onhand Quantity</h3>
      <p>{data.total_onhand_quantity}</p>
      <h3>Total Onhand Value</h3>
      <p>{formatter.format(data.total_onhand_quantity * Cost)}</p>
      <h3>Quantity by Fulfillment Center</h3>
      {centers.map((center) => {
        return (
          <div>
          <h4 key={center.name}>{center.name}</h4>
          <p key={center.onhand_quantity}>{`Onhand Quantity: ${center.onhand_quantity}`}</p>
          <p key={center.awaiting_quantity}>{`Awaiting Quantity: ${center.awaiting_quantity}`}</p>
          </div>

        );
      })}
      <div>

      </div>
    </div>
  )
}

知道我在哪里出错以及如何解决吗?

非常感谢。

【问题讨论】:

    标签: reactjs react-hooks use-effect


    【解决方案1】:

    不确定你之前做了什么来得到这些错误,但你现在的代码看起来是正确的。您现在的问题是,无论 API_ENDPOINT 是什么都没有启用 CORS。这意味着服务器没有将您的域列入“您可以发出请求”的白名单,因此当它访问您的浏览器时,您的浏览器会通过使您的 fetch 调用无效来“保护”您。

    为了解决这个问题,您需要在 API 服务器上启用 CORS,并且需要将运行 UI 的域列入白名单。或者您可以创建自己的 API 并从那里提取数据,然后您可以从他们的 API 服务器端获取数据,这样您的浏览器就不会 CORS 拒绝您。

    旁注,我不确定我是否正确,但这可能会给您带来问题:

    setData(data);
    const centers = await data.fulfillable_quantity_by_fulfillment_center;
    setCenters(centers);
    

    或者至少它只是非常未优化。 React 将设置状态,重新渲染组件,同时等待第二次 fetch 调用完成,然后再次设置状态并重新渲染。

    改为进行所有 fetch 调用,然后设置所有状态,以便 react 可以通过批量更新渲染组件。

    【讨论】:

    • 感谢您的回复。我不控制 API 服务器,但我会寻求支持。我仍然不明白为什么会有这么多请求发生,每个唯一的 Inventory_ID 应该只有一个请求,我的应用程序有六个。知道如何将请求限制为仅加载一次吗?
    • 您还可以创建自己的 API 服务器端并在那里获取数据,这样您就不会使 CORS 失效,CORS 只是一个浏览器策略,所以如果您从他们的 API 服务器端获取然后获取从您自己的 API 它将起作用。此外,由于数据返回后状态更新,您的组件一直在重新渲染。您应该在一个地方进行所有状态更新,而不是在每个数据返回之后,您还应该使用useEffect 返回数组来保持状态,即useEffect(() =&gt; {}, [inventoryId]),以防止它一遍又一遍地呈现。
    • 谢谢。我是一名新开发人员,因此创建自己的 API 服务器端远远超出了我的能力。任何机会您都可以向我展示您的意思是“此外,一旦数据返回,由于状态更新,您的组件一直在重新渲染。您应该在一个地方完成所有状态更新,”我将如何在我的代码中完成此操作?此外,我尝试在 useEffect 依赖数组中包含 prop 'Inventory_ID',但收到关于它缺少依赖项 'fetchData' 的相同警告。我知道我需要更好地了解状态和挂钩的工作原理,因此感谢您的帮助!
    • 每次调用setSomething都会触发组件的重新渲染,所以如果你等待数据,然后设置它,然后等待数据,然后设置它,你在重复重新渲染组件并在每次渲染时触发useEffect。取而代之的是获取您想要的所有数据,然后设置所有状态。除此之外,错误告诉您将fetchData 函数移动到useEffect 中,所以这样做。此外,fetchData 不应添加到数组中,datacenters 应该。
    • 谢谢!我删除了centers 以简化问题,然后将我的fetchData 函数移到useEffect 中。依赖数组调用Inventory_ID(就像您最初建议的那样)而不是data,所以我将Inventory_ID 添加到数组中,它现在可以正常工作而没有任何警告。现在我只需要返回并弄清楚如何在不触发重新渲染的情况下添加回centers。我遇到的问题是 centers 是一个数组,所以我不确定如何在同一个 setState 中处理它
    猜你喜欢
    • 2022-01-11
    • 1970-01-01
    • 2020-08-09
    • 2019-08-09
    • 2021-09-29
    • 1970-01-01
    • 2020-04-29
    • 2020-12-23
    • 2022-06-12
    相关资源
    最近更新 更多