next.js window 的 P5js 即使在 useEffect 中也没有定义

P5js with next.js window is not defined even in useEffect

我需要导入带有 p5.js 徽标的组件。当我收到错误时

window is not defined

我一直在寻找一些解决方案,发现在 useEffect 内部,只有在 window 对象变得可访问后才会挂载组件。

我试过那个日志来检查它是否有效:

  useEffect(() => {
    if (window !== undefined) 
    console.log('I am nont undefined');
     )
})

宾果,不是未定义

在那之后我试过了:

 useEffect(() => {
    if (window !== undefined) 
    console.log('I am nont undefined');
    return (
      <ReactP5Wrapper  sketch={sketch} mode='all_dir' />
      )
})

但是没有。 Window 未定义 ...

这是我的草图组件:

function sketch(p) {

    // console.log(props.mode_react)
    // UNITS
    let padding = [2,2]; // units
    let logo_dimensions = [80, 22]; // units
    let box_dimensions = [4, 1.65] // units
    // PIXELS
    let tile_size // pixels
    let box_size // pixels

    // INTERACTIVTY
    let modes = {
    MOUSE_DIR: 'mouse_dir',
    ALL_DIR: 'all_dir',
    NOISE: 'noise',
    MOUSE_NOISE: 'mouse_noise',
    FIXE: 'fixe'
    }
    let mode = modes.MOUSE_DIR;
    let zoff = 0;
    let zinc = 0.005;


    let letter_positions = [
        // F
        [4,3], [8,3], [12,3], [16, 3],
        [4,7],
        [4,11], [8,11], [12,11],
        [4,15],
        [4,19],
        // //A
        [26, 3],
        [24, 7], [28, 7],
        [22,11], [30,11],
        [20,15], [24,15], [28,15], [32,15],
        [18,19], [34,19],
        // //C
        [48,2], 
        [44, 4], [52, 4],
        [41,7], [55,7],
        [39,11],
        [41, 15], [55, 15],
        [44, 18], [52, 18],
        [48,20],
        // //T
        [60,3], [64,3], [68,3], [72,3], [76,3],
        [68,7],
        [68, 11],
        [68, 15],
        [68,19]
      ]      

    /////////////////////
    //     SETUP       //
    /////////////////////
    p.setup = function() {
        let div_width = document.getElementById("logo_canvas").offsetWidth
        tile_size = div_width / (logo_dimensions[0]+padding[1]);
        // tile_size = p.windowWidth / (logo_dimensions[0]+padding[1]);
        box_size = [p.floor(tile_size*box_dimensions[0]), p.floor(tile_size*box_dimensions[1])]
        let canvas = p.createCanvas(div_width, tile_size*logo_dimensions[1]+padding[1]*tile_size)
        // let canvas = p.createCanvas(p.windowWidth, tile_size*logo_dimensions[1]+padding[1]*tile_size, p.P2D)
        // canvas.parent("logo_canvas")
    };

    p.windowResized = function() {
        p.setup()
      }
    

    ////////////////////
    //      DRAW      //
    ////////////////////
    p.draw = function() {
        p.background(220);
        p.translate(padding[0]*tile_size/2, padding[1]*tile_size/2)
        p.draw_logo();
        zoff += zinc;
    }

    
    p.draw_logo = function() {
        p.rectMode(p.CENTER);
        letter_positions.forEach(function(letter_position) {
        p.push();
        
        let x = letter_position[0]*tile_size ;
        let y = letter_position[1]*tile_size;
        p.translate(x, y);
        p.fill(0);
    
        let angle = p.get_angle(x, y) ;
        p.rotate(angle);  
        
        p.rect(0, 0, box_size[0], box_size[1]);
        p.pop();
        }
        ) 
    
    }
  

    /////////////////////////
    //       MODES         //
    /////////////////////////
    p.get_angle = function(x, y ) {
        if (mode === modes.MOUSE_DIR) {
        return p.mouse_dir(x, y)
        } else if (mode === modes.ALL_DIR) {
        return p.mouse_all(x, y)
        } else if (mode === modes.NOISE) {
        return p.noise_dir(x,y)
        } else if (mode === modes.FIXE) {
        return 0
        } else if (mode === modes.MOUSE_NOISE) {
        return p.mouse_noise_dir(x, y)
        }
        return 0   
    }
    
    
    p.mouse_dir = function(x, y) {
        return p.atan2( p.mouseY-y-padding[1]/2*tile_size, p.mouseX-x-padding[0]/2*tile_size)
    }
    
    p.noise_dir = function(x, y) {
        let value = p.noise(x, y, zoff);
        value *= p.TWO_PI;
        return value
        
    }
    
    p.mouse_noise_dir = function(x, y) {
        let value = p.noise(x, y, p.mouseX*zinc);
        value *= p.TWO_PI;
        return value
    }
    
    p.mouse_all = function(x, y) {
        return p.map(p.mouseX, 0, p.width, 0, p.PI)
    }
    
    /////////////////////
    //       PROPS     //
    /////////////////////
    p.updateWithProps = props => {
        if (props.mode) {
          mode = props.mode
        }
      };
}

export default sketch;

nav.js

import { ReactP5Wrapper } from "react-p5-wrapper";
import sketch from './sketch';


const Nav = () => {
  const { cursorType, cursorChangeHandler } = useContext(MouseContext);

  useEffect(() => {
    if (window !== undefined) 
    console.log('I am nont undefined');
    return (
      <ReactP5Wrapper  sketch={sketch} mode='all_dir' />
      )
})

  return (

您还需要什么吗?

就像 juliomalves 所建议的那样,我使用动态导入 next/dynamic

https://nextjs.org/docs/advanced-features/dynamic-import#with-named-exports

没有 SSR 时这样使用:

import dynamic from 'next/dynamic'

const DynamicComponentWithNoSSR = dynamic(
  () => import('../components/hello3'),
  { ssr: false }
)

function Home() {
  return (
    <div>
      <Header />
      <DynamicComponentWithNoSSR />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home