为什么渲染Material-UI组件时renderToString会引发有关useLayoutEffect的错误?

时间:2019-12-25 16:53:11

标签: javascript reactjs material-ui react-leaflet

我正在使用React v.16.12.0和@ MaterialUI / core v4.8.1。

我正在尝试为React Leaflet Marker创建自定义图标。图标是Material-UI中的Fab组件。为此,我需要将HTML字符串传递给L.DivIcon (DivIcon Docs) Leaflet组件,因此我正在使用renderToString()中的react-dom/server方法。

它抛出一个错误:

  

警告:useLayoutEffect在服务器上不执行任何操作,因为其效果无法被编码为服务器渲染器的输出格式。这将导致初始的非水化用户界面与预期的用户界面不匹配。为避免这种情况,useLayoutEffect仅应在专门在客户端上呈现的组件中使用。       在NoSsr中       在按钮上       在ForwardRef(ButtonBase)中       在WithStyles(ForwardRef(ButtonBase))中       在ForwardRef(Fab)中       在WithStyles(ForwardRef(Fab))中(位于src / index.js:9)

虽然我没有使用useLayoutEffect。

这是一个简单的示例:

import React from "react";
import ReactDOM from "react-dom";
import ReactDOMServer from 'react-dom/server';
import Fab from '@material-ui/core/Fab';

function App() {
  return ReactDOMServer.renderToString(
    <Fab size="small" variant="extended">
      Test
    </Fab>);
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

在线:https://codesandbox.io/s/material-ui-rendertostring-tc90b

为什么会抛出该错误?此代码有什么不对?是否还有其他方法可以从Material-UI组件生成HTML字符串,以将其作为图标传递给Leaflet Marker?

1 个答案:

答案 0 :(得分:0)

我使用renderToStaticMarkup来渲染自定义标记。标记已呈现,但仍收到警告。

import React, { Component } from "react";
import ReactDOM from "react-dom";
import { renderToStaticMarkup } from "react-dom/server";
import { divIcon } from "leaflet";
import { Map, TileLayer, Marker, Popup } from "react-leaflet";
import Fab from "@material-ui/core/Fab";

import "./styles.css";

class App extends Component {
  state = {
    lat: 51.505,
    lng: -0.091,
    zoom: 13
  };

  render() {
    const position = [this.state.lat, this.state.lng];
    const iconMarkup = renderToStaticMarkup(
      <Fab size="small" variant="extended">
        Test
      </Fab>
    );
    const customMarkerIcon = divIcon({
      html: iconMarkup
    });

    return (
      <div>
        <Map center={position} zoom={this.state.zoom}>
          <TileLayer
            attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            url="https://{s}.tile.osm.org/{z}/{x}/{y}.png"
          />
          <Marker position={position} icon={customMarkerIcon}>
            <Popup>
              A pretty CSS3 popup. <br /> Easily customizable.
            </Popup>
          </Marker>
        </Map>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

工作代码:https://codesandbox.io/s/react-leaflet-icon-material-mx1iu