0

我目前正在前端使用 Next.js 使用 Wordpress API。我想获取我的导航/菜单数据并进行预渲染。<nav> </nav>我已经尝试过,但是当我检查源代码时只呈现一个空元素。有一个简单的解决方案吗?

这是我的导航组件:

import { Config } from "../config";
import Link from "next/link";
import useFetch from "../hooks/useFetch";

    export default function MainNav() {
      const links = useFetch(`${Config.apiUrl}/wp-json/menus/v1/menus/main-nav`);
    
      return (
        <nav>
          {!!links &&
            links.map((link) => (
              <Link href="/">
                <a>{link.title}</a>
              </Link>
            ))}
        </nav>
      );
    }

还有我的自定义useFetch.js钩子:

import { useEffect, useState } from "react";

export default function useFetch(url) {
  const [links, setLinks] = useState();

  //   Must use useEffect in non-page component

  useEffect(async () => {
    let res = await fetch(url);
    res = await res.json();
    setLinks(res.items);
  }, []);

  return links;
}
4

2 回答 2

0

所以我想通了,我在组件嵌套的页面上获取链接数据,然后使用组件组合将数据向下传递。问题是我必须直接将它们全部嵌套在页面上。如果有人有更优雅的解决方案,请告诉我:)

页面index.js

import PostIndex from "../components/PostIndex";
import Layout from "../components/Layout";
import Header from "../components/Header";
import MainNav from "../components/MainNav";

import { Config } from "../config";

export default function Home(props) {
  return (
    <Layout>
      <Header>
        <MainNav links={props.links} />
      </Header>
      <h2>Home Page</h2>
      <PostIndex limit={3} />
    </Layout>
  );
}

export async function getServerSideProps() {
  const [data1, data2] = await Promise.all([
    fetch(`${Config.apiUrl}/wp-json/wp/v2/posts?per_page=3`),
    fetch(`${Config.apiUrl}/wp-json/menus/v1/menus/main-nav`),
  ]);
  const posts = await data1.json();
  const links = await data2.json();
  return {
    props: {
      posts,
      links,
    },
  };
}

Layout.js组件:

export default function Layout({ children }) {
  return <div>{children}</div>;
}

Header.js组件:

import Link from "next/link";

export default function Header({ children }) {
  return (
    <div>
      <Link href="/">
        <a>
          <h1>Wordpress Blog</h1>
        </a>
      </Link>
      {children}
    </div>
  );
}

MainNev.js组件:

import { Config } from "../config";
import Link from "next/link";

export default function MainNav({ links }) {
  return (
    <nav>
      {!!links &&
        links.items.map((item) => (
          <Link href="/">
            <a>{item.title}</a>
          </Link>
        ))}
    </nav>
  );
}
于 2020-10-25T13:15:05.497 回答
0

首先 useEffect 根本不是异步的,即使您asyncuseEffect回调函数中定义,正确的方法是设置单独的状态 -useState(false)用于微调器或将其包含到现有的状态中,这将控制微调器,因为您正在通过 REST 获取数据,基本上完整的示例应如下所示:

useFetch.js钩:

import { useEffect, useState } from "react";

export default function useFetch(url) {
  const [{ links, isLoading }, setLinks] = useState({ links: [], isLoading: true });

  //   Must use useEffect in non-page component

  useEffect(() => {
    (async funtion() {
      const res = await fetch(url);
      const { items } = await res.json();
      setLinks({ links: items, isLoading: false });
    })()
   
  }, []);

  return [isLoading, links];
}

Nav.js零件:

import { Config } from "../config";
import Link from "next/link";
import useFetch from "../hooks/useFetch";

    export default function MainNav() {
      const [links, isLoading] = useFetch(`${Config.apiUrl}/wp-json/menus/v1/menus/main-nav`);

      if(isLoading) {
        return <Spinner/>
      }
    
      return (
        <nav>
          {!!links && !isLoading &&
            links.map((link) => (
              <Link href="/">
                <a>{link.title}</a>
              </Link>
            ))}
        </nav>
      );
    }

于 2020-10-25T10:43:23.933 回答