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;
修复方案
核心问题点
filteredCat初始值为null,首次渲染时filteredCat && ...条件不成立,导致无内容展示- 初始化
filteredCat的useEffect逻辑错误,调用setLists()是无效操作 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
相关产品推荐
相关产品推荐

