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

从Strapi API获取单类型数据时React .map重复渲染问题

问题描述

使用React的.map方法从Strapi API获取单类型数据时,页面会重复渲染同一条内容两次;但获取集合类型数据时一切正常。期望只渲染1条对应的数据,而非重复记录。

原因分析

  • Strapi单类型API返回的data是单个对象(包含id和attributes两个属性),你用Object.values(objecthere)将这个对象转换成了数组,数组长度为2(对应id和attributes两个值),因此.map会执行两次
  • 你在.map回调中没有使用循环的当前项,而是直接引用整个objecthere对象,导致两次循环都渲染了完全相同的内容
  • 组件初始状态useState([])设置为数组,但单类型数据是对象,类型不匹配也会导致后续处理逻辑异常

修复方案

  1. 将状态初始值改为空对象(或null),匹配单类型数据的结构
  2. 不需要使用.map遍历,直接判断数据存在后渲染单条内容即可
  3. 渲染时直接使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 21:37:48