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

React项目:API列表首渲染不展示,需实现首屏显示完整列表

问题描述

我通过API获取了一个列表,可根据输入进行过滤,但首次渲染时页面无内容,只有点击按钮后才会显示对应过滤结果。我用React实现了按钮过滤功能,但需要首次渲染时就展示完整的列表,以下是我的代码:

import Button from "react-bootstrap/Button";
import Card from "react-bootstrap/Card";
import Container from "react-bootstrap/Container";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import { useEffect, useState } from "react";

function News() {
  const [news, setNews] = useState([]);
  const [listing, setLists] = useState([]);

  const fetchDataList = () => {
    return fetch("https://api.npoint.io/d275425a434e02acf2f7")
      .then((response) => response.json())
      .then((data) => {
        setLists(data.News);
       // data.News[0].id = 0;
        console.log(listing);
      });
  };

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

  const fetchData = () => {
    return fetch("https://api.npoint.io/91298d970c27e9a06518")
      .then((response) => response.json())
      .then((data) => {
        setNews(data.newsCategory);
        console.log(news);
      });
  };

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

  const [filteredCat, setFiltredCat] = useState(null);
  useEffect(() => {
    setFiltredCat(setLists());
  }, []);

  function filteredCategory(typecat) {
    let filteredCategory = listing.filter(
      (type) => type.categoryID === typecat
    );
    return filteredCategory;
  }
  function handleCategory(e) {
    let typeCategory = e.target.id

  typeCategory
      ? setFiltredCat(filteredCategory(typeCategory))
      : filteredCategory(setLists);
  }

  return (
    <>
      <p>Media</p>
      <h2>Top </h2>

      <div>
        {news &&
          news.map((idx) => (
            <Button id={idx.id} variant="secondary" onClick={handleCategory}>
              {idx.id} {idx.name}
            </Button>
          ))}
      </div>

      <Container>
        <Row>
          <Col>
            {filteredCat &&
              filteredCat.map((list) => (
                <Card style={{ width: "18rem" }}>
                  <Card.Img variant="top" src="holder.js/100px180" />
                  <Card.Body>
                    <Card.Title>{list.title}</Card.Title>
                    <Card.Text>{list.description}</Card.Text>
                    <Button variant="primary">{list.categoryID}</Button>
                  </Card.Body>
                </Card>
              ))}
          </Col>
        </Row>
      </Container>
    </>
  );
}

export default News;
修复方案

核心问题点

  1. filteredCat初始值为null,首次渲染时filteredCat && ...条件不成立,导致无内容展示
  2. 初始化filteredCat的useEffect逻辑错误,调用setLists()是无效操作
  3. handleCategory的else分支逻辑错误,未正确设置完整列表

修改后的代码

import Button from "react-bootstrap/Button";
import Card from "react-bootstrap/Card";
import Container from "react-bootstrap/Container";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import { useEffect, useState } from "react";

function News() {
  const [news, setNews] = useState([]);
  const [listing, setLists] = useState([]);
  // 初始化filteredCat为空数组,后续自动同步完整列表
  const [filteredCat, setFiltredCat] = useState([]);

  const fetchDataList = () => {
    return fetch("https://api.npoint.io/d275425a434e02acf2f7")
      .then((response) => response.json())
      .then((data) => {
        setLists(data.News);
      });
  };

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

  // 监听listing的变化,数据加载完成后自动设置为完整列表
  useEffect(() => {
    if (listing.length > 0) {
      setFiltredCat(listing);
    }
  }, [listing]);

  const fetchData = () => {
    return fetch("https://api.npoint.io/91298d970c27e9a06518")
      .then((response) => response.json())
      .then((data) => {
        setNews(data.newsCategory);
      });
  };

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

  function filteredCategory(typecat) {
    return listing.filter((type) => type.categoryID === typecat);
  }

  function handleCategory(e) {
    const typeCategory = e.target.id;
    // 有分类ID则过滤,否则展示完整列表
    typeCategory
      ? setFiltredCat(filteredCategory(typeCategory))
      : setFiltredCat(listing);
  }

  return (
    <>
      <p>Media</p>
      <h2>Top </h2>

      <div>
        {news.map((idx) => (
          // 列表渲染添加唯一key,符合React规范
          <Button
            key={idx.id}
            id={idx.id}
            variant="secondary"
            onClick={handleCategory}
          >
            {idx.id} {idx.name}
          </Button>
        ))}
      </div>

      <Container>
        <Row>
          <Col>
            {filteredCat.map((list) => (
              // 列表渲染添加唯一key
              <Card key={list.id} style={{ width: "18rem" }}>
                <Card.Img variant="top" src="holder.js/100px180" />
                <Card.Body>
                  <Card.Title>{list.title}</Card.Title>
                  <Card.Text>{list.description}</Card.Text>
                  <Button variant="primary">{list.categoryID}</Button>
                </Card.Body>
              </Card>
            ))}
          </Col>
        </Row>
      </Container>
    </>
  );
}

export default News;

关键修改说明

  • 将filteredCat初始值设为[],同时添加监听listing的useEffect,当API返回的完整列表加载完成后,自动把filteredCat设置为完整的listing,确保首次渲染就能展示内容
  • 移除了原代码中错误的setFiltredCat(setLists())逻辑,改为直接使用listing数据
  • 修正handleCategory的else分支,直接调用setFiltredCat(listing)来展示完整列表
  • 给所有列表渲染的元素添加了key属性,符合React的列表渲染规范
  • 移除了无效的console.log(状态更新是异步的,原代码中的console.log无法获取最新状态)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 15:31:41