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

React Hooks组件持续重复渲染,API返回内容随机变化问题求助

解决React Hooks重复渲染与API数据随机变化的问题

嘿,我来帮你搞定这个问题!你的组件一直重复渲染、数据随机变化的核心原因很明确:你的useEffect没有设置依赖数组,导致每次组件渲染时都会重新调用API请求,而你用的是随机鸡尾酒接口,所以每次请求都会返回新数据,进而触发组件重新渲染,形成了无限循环。

下面是具体的修复步骤:

1. 修复useFetch中的useEffect依赖

在你的useFetch.jsx里,useEffect目前没有任何依赖,这意味着它会在组件的每次渲染周期都执行。我们需要给它添加依赖数组,只有当传入的url变化时才重新发起请求:

import { useState, useEffect } from "react";

function useFetch(url) {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);

  async function fetchUrl() {
    const response = await fetch(url);
    const json = await response.json();
    setData(json);
    setLoading(false);
  }

  useEffect(() => {
    fetchUrl();
  }, [url]); // 这里添加url作为依赖,只有url改变时才重新请求

  return [data, loading];
}

export default useFetch;

这样修改后,只有当url发生变化时,才会重新调用API,而不是每次组件渲染都请求,就不会再无限获取随机数据了。

2. 优化列表渲染的key属性

在Main.jsx的map循环里,你把key加在了内部的div上,这不符合React的最佳实践——key应该绑定在循环的最外层元素上,这样React才能正确识别列表项:

{data.drinks.map(
  ({ idDrink, strDrink, strAlcoholic, strGlass, strDrinkThumb }) => (
    <Container key={idDrink}> {/* 将key移到最外层的Container上 */}
      <img src={strDrinkThumb} alt={strDrink} /> {/* 补充有意义的alt文本,提升可访问性 */}
      <div>{strDrink}</div>
    </Container>
  )
)}

3. 修复搜索框的小问题

你的Search组件里写了val,这应该是value属性的笔误。如果要实现搜索功能,还需要用useState来管理输入值:

import React, { useState } from "react"; // 引入useState
import styled from "styled-components";
import useFetch from "./useFetch";
import "./font.css";

const url = "https://www.thecocktaildb.com/api/json/v1/1/random.php";

const Main = () => {
  const [data, loading] = useFetch(url);
  const [searchTerm, setSearchTerm] = useState(""); // 添加搜索状态管理

  return (
    <Wrapper>
      <Header>My Cocktail Recipe</Header>
      {loading ? (
        "Loading..."
      ) : (
        <>
          {data.drinks.map(
            ({ idDrink, strDrink, strAlcoholic, strGlass, strDrinkThumb }) => (
              <Container key={idDrink}>
                <img src={strDrinkThumb} alt={strDrink} />
                <div>{strDrink}</div>
              </Container>
            )
          )}
        </>
      )}
      <Search 
        type="text" 
        placeholder="검색하세요" 
        value={searchTerm} // 绑定value
        onChange={(e) => setSearchTerm(e.target.value)} // 添加输入变化的处理函数
      />
    </Wrapper>
  );
};

export default Main;

做完这些修改后,你的组件就只会在初始加载时请求一次随机鸡尾酒数据,不会再持续重复渲染和随机变化了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:34:47