web-dev-qa-db-fra.com

Dépliant avec next.js?

Je reçois une référenceError:

la fenêtre n'est pas définie lors de l'utilisation de Next.js avec une notice.js.

Vous vous demandez s'il existe une solution simple à ce problème - utilise Next.js surcharge mon flux de travail?

pour ceux qui curieux avec le code exact,

import React, { createRef, Component } from "react";
import L from "leaflet";
import { Map, TileLayer, Marker, Popup, DivOverlay } from "react-leaflet";
import axios from "axios";
import Header from "./Header";


export default class PDXMap extends Component {
  state = {
    hasLocation: false,
    latlng: {
      lat: 45.5127,
      lng: -122.679565
    },
    geoJSON: null
  };

  mapRef = createRef();

  componentDidMount() {
    this.addLegend();
    if (!this.state.hasLocation) {
      this.mapRef.current.leafletElement.locate({
        setView: true
      });
    }
    axios
      .get(
        "https://opendata.arcgis.com/datasets/40151125cedd49f09d211b48bb33f081_183.geojson"
      )
      .then(data => {
        const geoJSONData = data.data;
        this.setState({ geoJSON: geoJSONData });
        return L.geoJSON(this.state.geoJSON).addTo(
          this.mapRef.current.leafletElement
        );
      });
  }

  handleClick = () => {
    this.mapRef.current.leafletElement.locate();
  };

  handleLocationFound = e => {
    console.log(e);
    this.setState({
      hasLocation: true,
      latlng: e.latlng
    });
  };

  getGeoJsonStyle = (feature, layer) => {
    return {
      color: "#006400",
      weight: 10,
      opacity: 0.5
    };
  };

  addLegend = () => {
    const map = this.mapRef.current.leafletElement;
    L.Control.Watermark = L.Control.extend({
      onAdd: function(map) {
        var img = L.DomUtil.create("img");

        img.src = "https://leafletjs.com/docs/images/logo.png";
        img.style.width = "200px";

        return img;
      }
    });

    L.control.watermark = function(opts) {
      return new L.Control.Watermark(opts);
    };

    L.control.watermark({ position: "bottomleft" }).addTo(map);
  };

  render() {
    const marker = this.state.hasLocation ? (
      <Marker position={this.state.latlng}>
        <Popup>
          <span>You are here</span>
        </Popup>
      </Marker>
    ) : null;

    return (
      <Map
        className="map-element"
        center={this.state.latlng}
        length={4}
        onClick={this.handleClick}
        setView={true}
        onLocationfound={this.handleLocationFound}
        ref={this.mapRef}
        zoom={14}
      >
        <TileLayer
          attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
        {marker}
      </Map>
    );
  }
}

/**
 * TODO:  Add Header + Legend to map
 *        - Header to be styled
 *        - Legend to be present in header
 *
 */


import React from 'react';
import PDXMap from "../components/map";


export default function SignIn() {
  const classes = useStyles();

  return (
      <PDXMap/>
);
}

Je suis heureux d'utiliser n'importe quelle voie à suivre - juste intéressé à obtenir un produit fonctionnel.

Acclamations!

Mettre à jour

Salut tout le monde,

Je reçois toujours cette erreur (est revenue un peu plus tard que j'avais planifié haha).

Je suis actuellement en train d'utiliser cette approche avec Useeffects,

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

function RenderCompleted() {

    const [mounted, setMounted] = useState(false);

    useEffect(() => {
        setMounted(true)

        return () => {
            setMounted(false)
        }
    });

    return mounted;
}

export default RenderCompleted;

et c'est la page qu'il montre sur

import React, { useEffect } from "react";
import Router, { useRouter } from "next/router";
import { useRef, useState } from "react";


//viz
import PDXMap from "../../components/Visualization/GIS/map";

import RenderCompleted from "../../components/utils/utils";

// import fetch from 'isomorphic-unfetch';
import { Cookies, CookiesProvider } from "react-cookie";
const cookies = new Cookies();
//containers

// Layouts
import Layout from "../../components/Layout/Layout_example";
import Chart from "../../components/Visualization/Graphs/Chart";
import Table from "../../components/Visualization/Tables/Table";
import Sidebar from "../../components/Layout/Sidebar/SidebarProperty";



export default function Bargains() {

  // const [inbrowser, setBrowser] = useState(false);

  const choiceRef = useRef<any>();
  const [message, setMessage] = useState<any>(null);

  const [productList, setProductList] = useState<any>([]);
  const [searched, setSearched] = useState(false);

  const router = useRouter();

  let token = cookies.get("token");

  // useEffect(() => {
  //   setBrowser(true);
  // });
  const isMounted = RenderCompleted();


  const columns = React.useMemo(
    () => [
    ....
    ],

    []
  )



  async function handleChoice() {

    console.log("searching...", choiceRef.current?.value);
    setMessage("Searching...");
    var headers = {
      "Content-Type": "application/x-www-form-urlencoded",
      "auth-token": token,
    };

    fetch(
    ....
  }


            <div className="flex flex-wrap ">
            {isMounted && <PDXMap/>}


              
              <Table columns={columns as any} data={productList as any} />


            </div>
          </div>



        </div>
      </div>


    </Layout>



  )
}

Avec le même message d'erreur de

ReferenceError: window is not defined

## Mettre à jour deux

D'accord, si étrangement, cela fonctionne lorsque je navigue sur le site d'une autre page, mais pas lorsque je charge la page elle-même.

J'aurai une réflexion sur cela, mais peut-être parce que la carte est en train de charger des données avec le composantDidMount () et qui interagit étrangement?

Mettre à jour

Ok j'ai créé un exemple plus simple basé sur https://github.com/rajeshdh/react-let-with-nextjs

Maintenant, il est en cours de chargement, mais les carreaux montrent de manière incorrecte, certains carreaux ne se chargent pas.

Ceci est la composante de carte que j'utilise pour être simple,

import React, { Component, createRef } from 'react';
import { Map, TileLayer, Marker, Popup, MapControl, withLeaflet } from 'react-leaflet';
import { GeoSearchControl, OpenStreetMapProvider } from 'leaflet-geosearch';


class SearchBox extends MapControl {
  constructor(props) {
    super(props);
    props.leaflet.map.on('geosearch/showlocation', (e) => props.updateMarker(e));
  }

  createLeafletElement() {
    const searchEl = GeoSearchControl({
      provider: new OpenStreetMapProvider(),
      style: 'bar',
      showMarker: true,
      showPopup: false,
      autoClose: true,
      retainZoomLevel: false,
      animateZoom: true,
      keepResult: false,
      searchLabel: 'search'
    });
    return searchEl;
  }
}


export default class MyMap extends Component {
  state = {
    center: {
      lat: 31.698956,
      lng: 76.732407,
    },
    marker: {
      lat: 31.698956,
      lng: 76.732407,
    },
    zoom: 13,
    draggable: true,
  }

  refmarker = createRef(this.state.marker)

  toggleDraggable = () => {
    this.setState({ draggable: !this.state.draggable });
  }

  updateMarker = (e) => {
    // const marker = e.marker;
    this.setState({
      marker: e.marker.getLatLng(),
    });
    console.log(e.marker.getLatLng());
  }

  updatePosition = () => {
    const marker = this.refmarker.current;
    if (marker != null) {
      this.setState({
        marker: marker.leafletElement.getLatLng(),
      });
    }
    console.log(marker.leafletElement.getLatLng());
  }

  render() {
    const position = [this.state.center.lat, this.state.center.lng];
    const markerPosition = [this.state.marker.lat, this.state.marker.lng];
    const SearchBar = withLeaflet(SearchBox);

    return (
      <div className="map-root">
        <Map center={position} zoom={this.state.zoom} style={{
                        height:"700px"
                    }}>
          <TileLayer
            attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          />
          <Marker
            draggable={true}
            onDragend={this.updatePosition}
            position={markerPosition}
            animate={true}
            ref={this.refmarker}>
            <Popup minWidth={90}>
              <span onClick={this.toggleDraggable}>
                {this.state.draggable ? 'DRAG MARKER' : 'MARKER FIXED'}
              </span>
            </Popup>
          </Marker>
          <SearchBar updateMarker={this.updateMarker} />
        </Map>
        <style jsx>{`
                .map-root {
                  height: 100%;
                }
                .leaflet-container {
                 height: 400px !important;
                 width: 80%;
                 margin: 0 auto;
               }
           `}
        </style>
      </div>
    );
  }
}

Et de l'appeler, j'utilise cela,

const SimpleExample = dynamic(() => import("../../components/Visualization/GIS/map"), {
  ssr: false
}); 

Et ont essayé ceci {ismonté &&}

9
LeCoda
let divIcon, Map, TileLayer, Marker, Popup;
// first you must check your environment
if (process.browser) {
  // then you can import
  divIcon = require('leaflet').divIcon;
  Map = require('react-leaflet').Map;
  TileLayer = require('react-leaflet').TileLayer;
  Marker = require('react-leaflet').Marker;
  Popup = require('react-leaflet').Popup;
}
0
Роман

Créer un fichier loader.js, placez le code ci-dessous:

export const canUseDOM = !!(
    typeof window !== 'undefined' &&
            window.document &&
            window.document.createElement
    );

if (canUseDOM) {
    //example how to load jquery in next.js;
    window.$ = window.jQuery = require('jquery');
}

À l'intérieur de tout composant ou page importer le fichier

import {canUseDOM} from "../../utils/loader";
{canUseDOM && <FontAwesomeIcon icon={['fal', 'times']} color={'#4a4a4a'}/>}

ou version de crochet

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

function RenderCompleted() {

    const [mounted, setMounted] = useState(false);

    useEffect(() => {
        setMounted(true)

        return () => {
            setMounted(false)
        }
    });

    return mounted;
}

export default RenderCompleted;

Invoquer le crochet:

const isMounted = RenderCompleted();

{isMounted && <FontAwesomeIcon icon={['fal', 'times']} color={'#4a4a4a'}/>}

0
eroll.maxhuni