从Strapi API获取单类型数据时React .map重复渲染问题
问题描述
使用React的.map方法从Strapi API获取单类型数据时,页面会重复渲染同一条内容两次;但获取集合类型数据时一切正常。期望只渲染1条对应的数据,而非重复记录。
原因分析
- Strapi单类型API返回的
data是单个对象(包含id和attributes两个属性),你用Object.values(objecthere)将这个对象转换成了数组,数组长度为2(对应id和attributes两个值),因此.map会执行两次 - 你在
.map回调中没有使用循环的当前项,而是直接引用整个objecthere对象,导致两次循环都渲染了完全相同的内容 - 组件初始状态
useState([])设置为数组,但单类型数据是对象,类型不匹配也会导致后续处理逻辑异常
修复方案
- 将状态初始值改为空对象(或
null),匹配单类型数据的结构 - 不需要使用
.map遍历,直接判断数据存在后渲染单条内容即可 - 渲染时直接使用
objecthere的属性,避免错误的循环逻辑
完整修正代码
import { useEffect, useState } from 'react'; import { Link } from "react-router-dom"; // Parses the JSON returned by a network request const parseJSON = (resp) => (resp.json ? resp.json() : resp); // Checks if a network request came back fine, and throws an error if not const checkStatus = (resp) => { if (resp.status >= 200 && resp.status < 300) { return resp; } return parseJSON(resp).then(resp => { throw resp; }); }; const headers = { 'Content-Type': 'application/json' }; const BoxComponent = () => { const [error, setError] = useState(null); // 初始值改为空对象,匹配单类型数据结构 const [objecthere, setObjecthere] = useState({}); useEffect(() => { fetch('http://localhost:1337/api/boxdata?populate=*', { headers, method: 'GET' }) .then(checkStatus) .then(parseJSON) .then(({ data }) => setObjecthere(data)) .catch((error) => setError(error)) }, []) if (error) { return <div>An error occured: {error.message}</div>; } // 判断数据是否存在,存在则直接渲染单条内容 return ( <div className="container"> {objecthere.id && ( <div key={objecthere.id}> <section className="py-4 py-xl-5"> <div className="container"> <h2 className="font-weight-bold text-white mb-3"> {objecthere.id} {objecthere.attributes.TheBox.Title} </h2> <p className="mb-4">{objecthere.attributes.TheBox.TextContent}</p> <Link to="/contact"> <span className="btn btn-light btn-lg" role="button"> {objecthere.attributes.TheBox.ButtonText} </span> </Link> </div> </section> </div> )} </div> ); }; export default BoxComponent;
补充说明
如果后续需要兼容集合类型和单类型数据,可以添加判断逻辑:
// 在渲染部分 {Array.isArray(objecthere) ? objecthere.map(item => (/* 集合类型渲染逻辑 */)) : objecthere.id && (/* 单类型渲染逻辑 */) }
内容的提问来源于stack exchange,提问作者Jahs
相关产品推荐
相关产品推荐

