簡體   English   中英

在 Next.js 應用程序的頁面上動態加載組件

[英]Dynamically load components on a page in Next.js app

我有一個 Next.js 服務器端渲染應用程序,我需要在其中動態加載組件。

例如 Homepage,我在 getServerSideProps 中調用 API 來獲取主頁數據,其中包含有關頁面的一些基本信息以及所有組件的名稱和每個組件的數據。 從這里我需要在頁面正文中動態呈現這些組件。 並且這些動態組件需要在服務器上進行渲染以進行 SEO。

這是我的簡化代碼

import Head from 'next/head';
import Header from '../components/Header';
import Banner from '../components/Banner';

import { getDomainFromContext, getParamFromContext } from '../src/utils';
import { fetchPage } from '../src/fetchers';

export async function getServerSideProps(context) {
    const domain = getDomainFromContext(context);
    const locale = getParamFromContext(context, 'locale');
    const uri = '/';

    const page = await fetchPage(domain, uri, locale);

    /*
        page now has names of the components with data for each component. e.g
        {
            ...
            components : {
                {
                    "name" : "Venues",
                    "data" : "..."
                },
                {
                    "name" : "Info",
                    "data" : "..."
                }
            }
            ...
        }
     */


    return {
        props: {
            domain: domain,
            locale: locale,
            page: page
        },
    };
}

function Home(props) {
    
    return (
        <>
            <Head>
                <title>Create Next App</title>
                <meta name="description" content="Generated by create next app" />
                <link rel="icon" href="/favicon.ico" />
            </Head>

            <Header>
                <h1>Homepage</h1>
            </Header>

            <main>
                <Banner />
                {/*Load Dynamic components here & it should be server side rendered.*/}
            </main>
        </>
    );
}

export default Home;

所以我的解決方案基於這個問題的答案: 未知組件的動態導入 - NextJs

我創建了一個接受要加載的組件名稱的函數,一旦從 API 獲得組件名稱,我就會循環訪問組件名稱以加載並將它們保存在數組中,並將數據也保存在數組中。 后面的組件是從數組中渲染出來的。

import Head from 'next/head';
import Header from '../components/Header';
import { getDomainFromContext, getParamFromContext } from '../src/utils';
import { fetchPage } from '../src/fetchers';
import { Suspense } from 'react';


export function getDynamicComponent(c) {
    return dynamic(() => import(`../components/${c}`), {
        suspense: true,
    });
}

export async function getServerSideProps(context) {
    let domain = getDomainFromContext(context);
    let locale = getParamFromContext(context, 'locale');
    let pageUri = '/'


    const page = await fetchPage(companyId, pageUri);

    return {
        props: {
            domain: domain,
            locale: locale,
            page: page,
        },
    };
}

function Home(props) {
    
    let components = [];
    let componentsData = [];

    props.page.components.forEach((component, i) => {
        components.push(getDynamicComponent(component.name));
        componentsData.push(component.data);
    });

    return (
        <>
            <Head>
                <title>Create Next App</title>
                <meta name="description" content="Generated by create next app" />
                <link rel="icon" href="/favicon.ico" />
            </Head>

            <Header>
                <h1>Homepage</h1>
            </Header>

            <main>
                <Suspense fallback={`...`}>
                    {components.map((Component, k) => (
                        <Component key={k} data={componentsData.data[k]} />
                    ))}
                </Suspense>
            </main>
        </>
    );
}

export default Home;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM