Предупреждение: React не распознает опору `viewState` в элементе DOM

Я манипулирую состоянием компонента и использую объекты в состоянии (входные параметры) для отображения некоторой информации.

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>
  )
}

Но получил следующее предупреждение: я проверил, что не управляю состоянием элемента DOM или у меня есть какое-то свойство с именем viewState? Что означает предупреждение?

Предупреждение: React не распознает свойство viewState в элементе DOM. Если вы намеренно хотите, чтобы он отображался в модели DOM как настраиваемый атрибут, используйте вместо этого строчные буквы viewstate. Если вы случайно передали его из родительского компонента, удалите его из элемента DOM.

Полный код моего компонента показан ниже:

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>
  );
}

Я использовал какой-то сторонний пакет, чтобы отображать всплывающие подсказки на картах.

Свойства renderTooltip назначаются функцией input renderTooltip, о которой я упоминал выше, и я использую состояние tooltip, чтобы контролировать, следует ли отображать всплывающую подсказку на моей странице.

PS: согласно документам deck.gl, onHover будет срабатывать по адресу:

onHover (функция, необязательно)

Этот обратный вызов будет вызываться, когда мышь входит / покидает объект этого слоя deck.gl со следующими параметрами:

  • Информация

  • событие - исходное событие

Согласно пути трассировки ошибок, он выдает ошибку в моем элементе <span>, поэтому я сначала думаю, что это проблема renderTooltip.

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


person hijiangtao    schedule 22.01.2019    source источник
comment
Не могли бы вы показать код компонента?   -  person Hai Pham    schedule 22.01.2019
comment
Я не думаю, что это часть кода предупреждения исходит от   -  person aquilesb    schedule 22.01.2019
comment
@HaiPham Спасибо за напоминание! Я использовал какой-то сторонний пакет для отображения всплывающей подсказки на картах, и я реализую его в конце описания, я делаю его более понятным, удаляя некоторые бесполезные коды. :-)   -  person hijiangtao    schedule 22.01.2019
comment
@aquilesb То же, что и содержание выше. Спасибо большое. :-)   -  person hijiangtao    schedule 22.01.2019


Ответы (3)


Сегодня у меня была такая же проблема, и я решил ее, НЕ добавив всплывающую подсказку как прямой потомок 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>
  );

person MarkusL    schedule 04.03.2019
comment
Я попробовал этот способ и получил предупреждение при настройке состояния с обратным вызовом onHover. У вас была такая же ситуация раньше? - person hijiangtao; 01.04.2019

Похоже, это предупреждение исходит от deck.gl, попробуйте изменить компонент Map:

const Map = (props) => {
  const {
    controller = true,
    baseMap = true,
    initialViewState = INITIAL_VIEW_STATE,
    layerType = '3d-heatmap',
    renderTooltip = DEFAULT_RENDER_TOOLTIP,
    ...rest //rest props
  } = props;
//...
person Hai Pham    schedule 22.01.2019
comment
Спасибо! У меня вопрос, следует ли где-то использовать объект rest, иначе зачем мне передавать бесполезные свойства другому объекту? Относится ли это к внутренней проблеме deck.gl? - person hijiangtao; 22.01.2019
comment
Я попытался оставить другие неиспользуемые свойства, и я все равно буду получать ошибки, когда перемещаю мышь для отображения всплывающих подсказок, но не всегда, просто иногда, когда я обновляю страницу. - person hijiangtao; 22.01.2019
comment
Я вижу здесь логическую ошибку: {object && renderTooltip(tooltip)}. Если ваш if (объект) будет истинным событием, если он {}, попробуйте исправить это и обновить - person Hai Pham; 22.01.2019
comment
Я замечаю эту логику, но думаю, что она никогда не будет назначена {}, поскольку я инициализирую ее вначале с помощью useState, хотя я использую const { object } = tooltip || {}; в части рендеринга. - person hijiangtao; 22.01.2019
comment
@hijiangtao это сложное, я не знаком с deck.gl, поэтому не могли бы вы создать проект codeandbox.io чтобы упростить отслеживание? - person Hai Pham; 22.01.2019

Итак, я столкнулся с той же проблемой. Это тонкий вопрос, но похоже, что вы не должны передавать визуализированную всплывающую подсказку как дочерний элемент DeckGL, а скорее как функцию, которая будет отображать всплывающую подсказку при вызове. Итак, в вашем случае вы можете сделать это:

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

Вызов bind позволяет каррировать аргумент, который вы хотите передать, без фактического вызова базовой функции. Любые реквизиты, переданные DeckGL, будут переданы в качестве следующего аргумента после tooltip.

Есть и другие способы решить эту проблему, но главное - передать функцию, которая будет отображать не визуализированный компонент.

person tpett    schedule 26.04.2019