Home > database >  How to both dynamically import and render a component on button click in nextjs?
How to both dynamically import and render a component on button click in nextjs?

Time:01-31

I know that there are several nextjs and reactjs questions out there in this topic but I think this is specific enough to get an own thread. So I have a NextJS project where I want a button to disappear on click and then import a component dynamically and render it.

It is crucial to import the component dynamically because of 2 things.

  1. because we work with a library in the component which relies on 'window'
  2. because the component affects load time and we only need it when the 'init button' is clicked

Here is my index.js code so far:

import Head from "next/head";
import Image from "next/image";
import Link from "next/link";
import dynamic from "next/dynamic"
import React, { useEffect, useState } from "react";

import { Inter } from "@next/font/google";

const inter = Inter({ subsets: ["latin"] });


export default function Home() {

    return (
      <>
        <Head>
          <title>My page</title>
          <meta
            name='description'
            content="Some desc. content"
          />
          <meta name='viewport' content='width=device-width, initial-scale=1' />
          <link rel='icon' href='/favicon.ico' />
        </Head>
        <button onClick={initSurvey()}>Initialize!</button>
        
      </>
    )
    }

  function initSurvey(){
    console.log("The button is working!")
    const Survey = dynamic(() => import("../components/SurveyComponent"), {
      ssr: false,
    })
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Please keep in mind this is not all I could do I just cleaned up the failed attempts to deliver you a clean, readable and understandable snippet.

Thank you in advance!

CodePudding user response:

By checking the React.lazy documentation and this guide, I managed to get to this solution:

import { lazy, Suspense, useState } from "react";

const dynamicComponent = lazy(() => import('../components/MyDynamicComponent');

export default function Home() {

   const [dynComp, setDynComp] = useState(<div/>);

   const loadDynamicComponent = () => {

      return (
         <Suspense fallback={<div>Loading...</div>}>
            <dynamicComponent/>
         </Suspense>
      )
   }

   return (
      <>
         <button onClick={ () => setDynComp(<div>{loadDynamicComponent()}</div>)}>Initialize!</button>
         { dynState }
      </>
   );

}

Test it and let me know if it helps you!

  • Related