首页 > 解决方案 > 通过 WordPress REST API 循环浏览帖子类别 - React

问题描述

我试图找出使用 WordPress REST API 循环的问题。

是)我有的:

我正在使用其余 api 类别端点“/wp/v2/categories”。我正在遍历返回的每个类别(总共 7 个类别)并为每个类别创建一个按钮。到目前为止,我有这个工作。代码如下所示:

const Posts = ({ state }) => {

  const [categories, setCategories] = useState([]);
  useEffect(() => {
    fetch(state.source.api + "/wp/v2/categories")
      .then(response => response.json())
      .then(data => {
        setCategories(data);
      })
  }, []);
  console.log(categories);

  return (
    <>
      {categories.length > 0 ? (
        categories.map((category, i) => {
          return (
            <button key={i}>{category.name}</button>
          )
        })
      ) : (
          <p>Loading...</p>
        )
      }
    </>
  )
}

我正在尝试做的事情: 我试图在按钮下方有一个部分,当单击按钮时将列出每个类别的博客文章。因此,当页面最初加载时,所有博客帖子都已加载,但是当您单击“书籍”类别时,例如,只有“书籍”类别中的帖子会显示。我知道我必须为按钮创建一个事件处理程序,所以我将按钮更新为<button key={i} onClick={handleShowPosts}>{category.name}</button>,并开始创建:

const handleShowPosts = () => {

};

但我对如何做到这一点有点困惑。我需要{category.name}进入const handleShowPosts = ({category.name}) => {吗?在遍历每个类别以获取帖子时我将如何做到这一点?

编辑:

我应该澄清一下,查看所有帖子/wp/v2/categories的端点是,但查看特定类别帖子的端点是"/wp/v2/posts?categories=" + category.id

标签: javascriptreactjswordpress

解决方案


好吧,如果我没有误解你的目标和数据结构,这里有一个例子展示了你如何做到这一点。正如我在评论中试图解释的那样,您可以设置类别名称状态并有条件地呈现帖子。

const categoriesData = [
  {
    name: "books",
    posts: [
      { id: 1, name: "foo" },
      { id: 2, name: "bar" }
    ]
  },
  {
    name: "movies",
    posts: [
      { id: 1, name: "fizz" },
      { id: 2, name: "buzz" }
    ]
  }
];

function Main() {
  const [categories, setCategories] = React.useState(categoriesData);
  const [catName, setCatName] = React.useState();
  
  
  return (
    <React.Fragment>
      {categories.length > 0 ? (
        categories.map((category, i) => {
          return (
            <button key={i} onClick={() => setCatName(category.name)}>
              {category.name}
            </button>
          );
        })
      ) : (
        <p>Loading...</p>
      )}
      <div>
        {catName &&
          categories
            .find((category) => category.name === catName)
            .posts.map((post) => <div key={post.id}>{post.name}</div>)}
      </div>
    </React.Fragment>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Main />, rootElement);
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>



<div id="root" />

评论后更新

如果您要获取相关posts数据,那么您可以使用 a useEffect。我正在模仿下面的 API 请求。您可以据此调整您的代码。

const categoriesData = [
  {
    name: "books"
  },
  {
    name: "movies"
  }
];

const postsData = {
  books: [
    { id: 1, name: "foo" },
    { id: 2, name: "bar" }
  ],
  movies: [
    { id: 1, name: "fizz" },
    { id: 2, name: "buzz" }
  ]
};

function fakePostsApi(catName) {
  return new Promise((resolve) =>
    setTimeout(() => {
      resolve(postsData[catName]);
    }, 1000)
  );
}

function Main() {
  const [categories, setCategories] = React.useState(categoriesData);
  const [catName, setCatName] = React.useState();
  const [posts, setPosts] = React.useState([]);

  React.useEffect(() => {
    if (catName) {
      fakePostsApi(catName)
        .then(setPosts);
    }
  }, [catName]);

  return (
    <div>
      {categories.length > 0 ? (
        categories.map((category, i) => {
          return (
            <button key={i} onClick={() => setCatName(category.name)}>
              {category.name}
            </button>
          );
        })
      ) : (
        <p>Loading...</p>
      )}
      <div>
        {posts.length === 0 ? (
          <p>No posts...</p>
        ) : (
          posts.map((post) => <div key={post.id}>{post.name}</div>)
        )}
      </div>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Main />, rootElement);
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>



<div id="root" />

你可以以任何你喜欢的方式改进代码。例如,可能是一个loading状态并根据此显示“更新帖子”消息。这只是一个示例,旨在为您提供一个想法。

第二次更新

您将像对categories. 如果您使用类别 ID 而非名称进行请求,那么您可以据此更改我的示例。catName您将使用catIdstate 并在那里保留一个类别 ID,而不是拥有一个state。我只提供相关部分:

function Main() {
  const [categories, setCategories] = React.useState(categoriesData);
  const [catId, setCatId] = React.useState();
  const [posts, setPosts] = React.useState([]);

React.useEffect(() => {
  if (catId) {
    fetch(`${state.source.api}/wp/v2/posts?categories=${category.id}`)
      .then((response) => response.json())
      .then((data) => {
        setPosts(data);
      });
  }
}, [catId]);

当然,您应该在按钮onCLick中设置类别 ID,如下所示:

<button key={i} onClick={() => setCatId(category.id)}>
  {category.name}
</button>

推荐阅读