4
votes

Attention: React ne reconnaît pas le prop `viewState` sur un élément DOM

Je manipule l'état du composant et j'utilise les objets dans state (les paramètres d'entrée) pour afficher des informations.

Warning: React does not recognize the `viewState` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `viewstate` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
    in span (created by Map)
    in div (created by DeckGL)
    in div (created by DeckGL)
    in DeckGL (created by Map)
    in Map (created by SpatialTemporal)
    in section (created by SpatialTemporal)
    in SpatioMap
    in section
    in Unknown (created by LBS)
    in div
    in div
    in Unknown (created by LBS)
    in LBS (created by Connect(LBS))
    in Connect(LBS) (created by DynamicComponent)
    in DynamicComponent (created by Route)
    in Route (created by BasicLayout)
    in Switch (created by BasicLayout)
    in div (created by BasicLayout)
    in div (created by Basic)
    in Basic (created by Adapter)
    in Adapter (created by BasicLayout)
    in div (created by BasicLayout)
    in BasicLayout (created by Adapter)
    in Adapter (created by BasicLayout)
    in div (created by BasicLayout)
    in BasicLayout (created by Adapter)
    in Adapter (created by BasicLayout)
    in div (created by ContainerQuery)
    in ContainerQuery (created by BasicLayout)
    in DocumentTitle (created by SideEffect(DocumentTitle))
    in SideEffect(DocumentTitle) (created by BasicLayout)
    in BasicLayout (created by Connect(BasicLayout))
    in Connect(BasicLayout) (created by DynamicComponent)
    in DynamicComponent (created by Route)
    in Route (created by DvaRoot)
    in Switch (created by DvaRoot)
    in Router (created by DvaRoot)
    in LocaleProvider (created by DvaRoot)
    in Provider (created by DvaRoot)
    in DvaRoot

Mais j'ai reçu l'avertissement suivant, j'ai vérifié que je n'avais pas manipulé l'état sur un élément DOM, ou que j'avais une propriété nommée viewState ? Que signifie l'avertissement?

Attention: React ne reconnaît pas la prop viewState sur un élément DOM. Si vous souhaitez intentionnellement qu'il apparaisse dans le DOM en tant qu'attribut personnalisé, épelez-le plutôt en minuscules viewstate . Si vous l'avez passé accidentellement à partir d'un composant parent, supprimez-le de l'élément DOM.

Le code complet de mon composant s'affiche ci-dessous:

import React, { memo, useEffect, useRef, useState } from 'react';
import DeckGL, {HexagonLayer} from 'deck.gl';
import { StaticMap } from 'react-map-gl';

import { INITIAL_VIEW_STATE, LAYER_CONFIGS } from './configs';
import { addMapControl } from './tools';
import { MAPBOX_TOKEN } from './constants';
import styles from './index.less';

const Map = (props) => {
  const {
    controller = true,
    baseMap = true,
    initialViewState = INITIAL_VIEW_STATE,
    layerType = '3d-heatmap',
    renderTooltip = DEFAULT_RENDER_TOOLTIP,
  } = props;

  const [tooltip, setTooltip] = useState({
    object: null,
    // eslint-disable-next-line react/no-unused-state
    x: 0,
    // eslint-disable-next-line react/no-unused-state
    y: 0,
  })

  /**
   * layers render function
   */
  const renderLayers = () => {
    const {
      data,
      accData = [],
      accSpeed = 0.1,
      accRadiusScale = 4,
      accRadiusMaxPixels = 200,
      accColorRange,
      coverage = 1,
      radius,
      elevationScale,
      ...otherProps
    } = props;
    const layers = [];

    layers.push(
      new HexagonLayer({
        ...LAYER_CONFIGS.AugmentHexagonLayer,
        ...otherProps,
        coverage,
        data,
        radius,
        onHover: setTooltip,
      }),
    );

    return layers;
  }

  /**
   * add Control for language switching
   * @param {*} event 
   */
  const addControlHandler = (event) => {
    const map = event && event.target;
    if (map) {
      addMapControl(map);
    }
  };

  const { object } = tooltip || {};

  return (
    <DeckGL
      width="100%"
      height="100%"
      layers={renderLayers()} // eslint-disable-line
      initialViewState={initialViewState}
      controller={controller}
    >
      {baseMap && (
        <StaticMap
          onLoad={addControlHandler}
          reuseMaps
          mapStyle="mapbox://styles/mapbox/dark-v9"
          preventStyleDiffing
          mapboxApiAccessToken={MAPBOX_TOKEN}
        />
      )}
      {object && renderTooltip(tooltip)}
    </DeckGL>
  );
}

J'ai utilisé un package tiers pour afficher des info-bulles dans les cartes.

Les accessoires renderTooltip sont attribués par l'entrée renderTooltip code > fonction que j'ai mentionnée ci-dessus, et j'utilise l'état tooltip pour contrôler si je dois afficher l'info-bulle dans ma page.

PS: selon les documents de deck.gl, le onHover sera déclenché à:

onHover (Fonction, facultatif)

Ce rappel sera appelé lorsque la souris entre / sort d'un objet de ce calque deck.gl avec les paramètres suivants:

  • informations

  • événement - l'événement source

Selon le chemin de trace d'erreur, il jette l'erreur dans mon élément , c'est pourquoi je pense que c'est le problème de renderTooltip à d'abord.

const renderTooltip = ({ object: hoveredObject, x: pointerX, y: pointerY }) => {
  // console.log(hoveredObject);
  const {points} = hoveredObject;

  const calLoadTime = () => {
    const rawTime = points.reduce(
      (accumulator, currentValue) => 
      currentValue ? accumulator + currentValue.SPACES : accumulator, 
      0
    ) / points.length;

    return rawTime.toFixed(1);
  }

  return (
    <span
      style={{
        lineHeight: '20px',
        borderRadius: '3px',
        width: '200px',
        left: pointerX+10,
        top: pointerY+5,
      }}
    >
      {`Length: ${points.length}\n`}
    </span>
  )
}


4 commentaires

Pourriez-vous s'il vous plaît vous montrer le code du composant?


Je ne pense pas que ce soit la partie du code de l'avertissement qui vient


@HaiPham Merci pour le rappel! J'ai utilisé un package tiers pour faire afficher des info-bulles dans les cartes, et je l'implémente en bas de la description, je le clarifie en supprimant certains codes inutiles. :-)


@aquilesb Identique au contenu ci-dessus. Merci beaucoup. :-)


3 Réponses :


0
votes

Il semble que cet avertissement provienne de deck.gl, essayez de modifier le composant Map :

const Map = (props) => {
  const {
    controller = true,
    baseMap = true,
    initialViewState = INITIAL_VIEW_STATE,
    layerType = '3d-heatmap',
    renderTooltip = DEFAULT_RENDER_TOOLTIP,
    ...rest //rest props
  } = props;
//...


5 commentaires

Merci! J'ai une question, dois-je utiliser l'objet rest quelque part, sinon pourquoi devrais-je laisser des propriétés inutiles à un autre objet? Cela fait-il partie du problème interne de deck.gl?


J'ai essayé de mettre au repos d'autres propriétés inutilisées et j'obtiendrai toujours des erreurs lorsque je déplace la souris pour afficher des info-bulles, mais pas toujours, juste parfois lorsque j'actualise la page.


Je vois une erreur de logique ici: {object && renderTooltip (tooltip)} . Si (objet) sera un événement vrai si c'est {} , veuillez essayer de corriger cela et actualiser


Je remarque cette logique, mais je pense qu'elle ne sera jamais attribuée à {} , puisque je l'initialise au début avec useState , bien que j'utilise const {object } = info-bulle || {}; dans la partie rendu.


@hijiangtao c'est compiqué, je ne connais pas deck.gl, alors pourriez-vous s'il vous plaît créer un projet codesandbox.io pour faciliter le traçage?



3
votes

J'ai eu le même problème aujourd'hui et je l'ai résolu en N'ajoutant PAS l'info-bulle en tant qu'enfant direct de deckGL:

return (
  <React.Fragment>
    <DeckGL
      width="100%"
      height="100%"
      layers={renderLayers()} // eslint-disable-line
      initialViewState={initialViewState}
      controller={controller}
    >
      {baseMap && (
        <StaticMap
          onLoad={addControlHandler}
          reuseMaps
          mapStyle="mapbox://styles/mapbox/dark-v9"
          preventStyleDiffing
          mapboxApiAccessToken={MAPBOX_TOKEN}
        />
      )}
    </DeckGL>
    {object && renderTooltip(tooltip)}
 </React.Fragment>
  );


1 commentaires

J'ai essayé de cette façon et j'ai reçu un avertissement lors de la configuration de l'état avec le rappel onHover . Avez-vous eu la même situation avant?



0
votes

Donc, je rencontrais le même problème. C'est une question subtile, mais il semble que vous n'êtes pas censé passer l'info-bulle rendue en tant qu'enfant de DeckGL, mais plutôt en tant que fonction qui rendra l'info-bulle lorsqu'elle est appelée. Donc, dans votre cas, vous pouvez faire ceci:

  return (
    <DeckGL
      ...
    >
      ...
      {object && renderTooltip.bind(this, tooltip)}
    </DeckGL>
  );

L'appel à bind vous permet de curry l'argument que vous vouliez passer sans appeler la fonction sous-jacente. Tous les accessoires passés par DeckGL seront passés comme argument suivant après tooltip.

Il y a d'autres façons de résoudre cela aussi, mais la clé est de passer une fonction qui ne rendra pas un composant rendu.


0 commentaires