为什么我的 react .map 在从 API 获取时两次显示相同的结果?

问题描述 投票:0回答:2

我正在使用 React .map 从 strapi api 获取单一类型的数据,但是单一返回的内容在这个函数中被渲染了两次:

{ Object.values(objecthere).map(({ }) => )}

为什么会这样,我做错了什么,我怎样才能让它只渲染一次? 此代码在获取 strapi 的集合类型时效果很好,但不是单一类型。我期待代码呈现出数组中项目的确切数量,在本例中为 1,两次不是相同的记录。

完整代码如下:

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) {
    // Print errors if any
    return <div>An error occured: {error.message}</div>;
  }

  return (
    <div className="container">
        { Object.values(objecthere).map(({ }) => 
          <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;
  

正在获取的数据是这样的:

{
  "data": {
    "id": 1,
    "attributes": {
      "createdAt": "2023-03-19T11:04:03.351Z",
      "updatedAt": "2023-03-19T12:08:17.995Z",
      "publishedAt": "2023-03-19T11:06:53.616Z",
      "TheBox": {
        "id": 1,
        "Title": "Title here",
        "TextContent": "Tincidunt laoreet leo, adipiscing taciti tempor. Primis senectus sapien, risus donec ad fusce augue interdum.!",
        "ButtonText": "Read more",
        "ButtonURL": "#"
      }
    }
  },
  "meta": {
    
  }
}
reactjs next.js fetch-api strapi
2个回答
0
投票

问题是,您将 objecthere 变量设置为 json 响应中“数据”属性的内容。

这导致您的 objecthere 变量为:

{
  "id": 1,
  "attributes": {
    "createdAt": "2023-03-19T11:04:03.351Z",
    "updatedAt": "2023-03-19T12:08:17.995Z",
    "publishedAt": "2023-03-19T11:06:53.616Z",
    "TheBox": {
      "id": 1,
      "Title": "Title here",
      "TextContent": "Tincidunt laoreet leo, adipiscing taciti tempor. Primis senectus sapien, risus donec ad fusce augue interdum.!",
      "ButtonText": "Read more",
      "ButtonURL": "#"
    }
  }
}

在你的下一步中,你将这个对象的所有值作为一个带有 Object.values(objecthere) 的数组。这导致一个包含两个元素的数组:

[
  1,
  {
    "createdAt": "2023-03-19T11:04:03.351Z",
    "updatedAt": "2023-03-19T12:08:17.995Z",
    "publishedAt": "2023-03-19T11:06:53.616Z",
    "TheBox": {
      "id": 1,
      "Title": "Title here",
      "TextContent": "Tincidunt laoreet leo, adipiscing taciti tempor. Primis senectus sapien, risus donec ad fusce augue interdum.!",
      "ButtonText": "Read more",
      "ButtonURL": "#"
    }
  }
]

.map() 函数然后迭代该数组中的两个元素,因此被调用两次。因为您在 map 函数中引用了 objecthere 变量本身,所以您会得到两次呈现完全相同的内容。

如果你的数据只是单一类型,你应该把 Object.values(objecthere).map(({ }) 函数一起去掉,因为无论如何你直接访问 objecthere 的属性。

只需确保,如果变量不为 null 并且您使用 null 而不是空数组初始化 objecthere,则您只能访问 objecthere 属性:

const [objecthere, setObjecthere] = useState(null);

[...]

return (
  <div className="container">
    { objecthere != null &&
      <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>
);

0
投票

为什么地图不接受任何参数?并且应该在你的 jsx inside map 前后放置大括号。您的地图功能应该如下所示。

  return (
<div className="container">
    { Object.values(objecthere).map((value) => (
      <div key={ value.id }>
        <section className="py-4 py-xl-5">
          <div className="container">
            <h2 className="font-weight-bold text-white mb-3">{ value.id } { value.attributes.TheBox.Title}</h2>
            <p className="mb-4">{ value.attributes.TheBox.TextContent}</p><Link to="/contact"><span className="btn btn-light btn-lg" role="button">{ value.attributes.TheBox.ButtonText }</span></Link>
          </div>
        </section>
      </div>
    )}    
</div>)
);
© www.soinside.com 2019 - 2024. All rights reserved.