如何在nextjs中服务器呈现动态递归菜单?

时间:2018-12-04 09:21:48

标签: javascript reactjs next.js

我在nextjs中创建带有子菜单(递归)的站点导航。一切正常,在控制台日志选项卡中未发现任何错误。我已经完成了两个实验:一个具有静态菜单(例如,它是静态导航),另一个是从其余API中动态提取数据(例如,它是动态导航)。

但是,我发现导航处于一种奇怪的情况。一旦我使用了静态导航,它就会同时在客户端和服务器上呈现(我会查看源代码)。换句话说,我的动态导航仅在客户端上可用(我也从视图源代码进行检查)。我确定RecursiveMenu组件中有问题,但是我没有找到任何解决方案,因为它不会像我之前所说的那样产生任何错误。

有什么主意吗?

// menu lists from API
[
    {
        "ID": 1,
        "parent": 0,
        "title": "About Us",
        "url": "http://localhost.dev/about-us/",
        "object": "page",
        "children": []
    },
    {
        "ID": 2,
        "parent": 0,
        "title": "Hello world!",
        "url": "http://localhost.dev/hello-world/",
        "object": "post",
        "children": []
    },
    {
        "ID": 3,
        "parent": 0,
        "title": "More",
        "url": "#",
        "object": "custom",
        "children": [
            {
                "ID": 4,
                "parent": 3,
                "title": "Hello Dolly",
                "url": "http://localhost.dev/hello-dolly/",
                "object": "post",
                "children": []
            }
        ]
    }
]

这是我的静态导航:

import React from 'react'
import { Link } from '../../routes' // from next-routes

const Nav = () => (
    <nav>
      <ul>
        <li>
          <Link route="/">
            <a>Home</a>
          </Link>
        </li>
        <li>
          <Link route="post" params={{slug: "single-post"}}>
            <a>Single Post</a>
          </Link>
        </li>
        <li>
          <Link route="page" params={{slug: "sample-page"}}>
            <a dangerouslySetInnerHTML={{__html: "Sample &amp; Page"}} />
          </Link>
        </li>
      </ul>
    </nav>
)
export default Nav

这是我的递归组件:

import React from 'react'
import { Link } from '../../routes' // from next-routes

import parse from 'url-parse'

const RecursiveMenu = (props) => {
    const dontClick = (e) => {
        e.preventDefault();
    }
    return(
        <ul>
            {props.datamenu.length > 0 && props.datamenu.map((menu) => {

                // customize paths & slugs from rest
                let parsedUrl = parse(menu.url, true)
                let menuObject = menu.object
                let stripCustom = menuObject.indexOf('custom') === 0 ? '/' : menu.object
                let itemslug = parsedUrl.pathname.slice(1, -1) // remove slashes from "/hello-world/" to "hello-world"

                return(
                    <li key={menu.ID}>
                        {
                            menu.children.length > 0
                            ? (
                                // the route props will detects whether post. page, category, etc from object
                                <Link route={`${stripCustom}`} params={{slug: itemslug}} >
                                    <a dangerouslySetInnerHTML={{__html: menu.title}} onClick={(e) => dontClick(e)} />
                                </Link>
                            )
                            : (
                                // the route props will detects whether post. page, category, etc from object
                                <Link route={`${stripCustom}`} params={{slug: itemslug}} >
                                    <a dangerouslySetInnerHTML={{__html: menu.title}} />
                                </Link>
                            )
                        }
                        {
                            menu.children !== undefined
                            && menu.children.length > 0
                            && <RecursiveMenu datamenu={menu.children} />
                        }
                    </li>
                )
            })}
        </ul>
    )
}
export default RecursiveMenu

0 个答案:

没有答案