0

I am new to Next.JS and having a hard time adjusting myself to it. Especially around initializing an imported module in my useEffect(), as the module uses window which ssr cannot handle. Since it is not a component, I am not using the dynamic() here.

What I want to do is execute functions in the imported module, however it is giving me var.func is not a function error. I have tried several combinations, but none of them worked.

My attempt 1 - Use the variable which imported the module.

useEffect(() => {
  const runInit = async () => {
    const a = await import('MODULE_PATH')

    try {
      await a.init();
    } catch (e) {
    }
  }
  runInit()
},[]);

My attempt 2 - Store the imported module in a state.

const [mod, setMod] = useState(null);
useEffect(() => {
  const runInit = async () => {
    const a = await import('MODULE_PATH')
    setMod(a)
    try {
      await mod.init();
    } catch (e) {
    }
  }
  runInit()
},[]);

I also tried to set let m = new a but it did not work either. Can anyone please help me with calling functions in the imported module?

knobutan
  • 41
  • 3
  • 1
    Is the module you're trying to import controlled by yourself, or a third-party library? As an alternative to your approach you could import it as usual at the top of the file, and then dynamically import that component using `next/dynamic` with `{ ssr: false }`. See the second approach in [Why am I getting ReferenceError: self is not defined when I import a client-side library?](https://stackoverflow.com/a/66100185/1870780). – juliomalves Aug 07 '22 at 17:23

2 Answers2

0

I am new too. But I am using like below for sticky header

import React, {useState, useEffect} from 'react'

const Navbar = () => {
    const [nav, setNav] = useState(false);
    const [shadow, setShadow] = useState(false);

    useEffect(() => {
            const handleShadow = () => {
                if (window.scrollY >= 90) {
                    setShadow(true);
                } else {
                    setShadow(false);
                }
            };
            window.addEventListener('scroll', handleShadow);
        }, []);
}
Mushfiqur Rahman
  • 376
  • 1
  • 2
  • 15
  • Thank you for your input. However, my goal is to run third party module in useEffect. Maybe my fundamental understanding of use of module in Next.js is wrong. – knobutan Aug 06 '22 at 14:44
0

May you explain why you need to import the module inside the function block?
As the document said at the https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
import declarations can only be present in modules, and only at the top-level (i.e. not inside blocks, functions, etc.).
So it is not possible to import modules inside blocks or functions.

Edit:

You can import your module at the top of your document and use it inside component or function like:

import useRouter from 'next/router';
import React from 'react';
export const example = () => {
  const router = useRouter();
  React.useEffect(() => {
    function example(){
      if(router.query.id === 1){
        alert(1);
    };
    example();
  });
}
  • Thank you for your input. Unfortunately, the module I use includes `window` and since I am using Next.js (server side rendering), it results in error. That is the reason I put it in the useEffect() to run it afterwards. `ReferenceError: window is not defined` – knobutan Aug 06 '22 at 14:41
  • @knobutan It's a pleasure to help. Let's try importing your module at the top of your document, then call it in the useEffect(). `import Example from example`. `const a = new Example`. I hope it works. – Sepehr Alimohamadi Aug 07 '22 at 12:52