React.js:是否可以将react组件转换为HTML DOM?

Jih*_*ada 17 javascript reactjs

我正在开发一个基于地图的应用程序,该应用程序使用Google Map API在React.js中创建标记及其信息窗口.在infowindow.setContent()仅接受或者是StringHTML.我无法传入,String因为我button链接到另一个反应组件中的特定方法(类似于:) _this.props.addList(place).因此,我必须将参数填充为HTML DOM,如下面的代码行:

var div = document.createElement('div');
var title = document.createElement('h4');
title.innerHTML = place.name;

var btn = document.createElement('button');
btn.className = 'btn btn-danger btn-block';
btn.appendChild(document.createTextNode('I want to go here !!'));

div.appendChild(title).appendChild(btn);

google.maps.event.addListener(marker, 'click', function() {

  infowindow.setContent( div );
  infowindow.open(map, this);
});

btn.addEventListener('click', function() {
  _this.props.addList(place);
});
Run Code Online (Sandbox Code Playgroud)

这些代码对我有用,但我不想一个一个地创建元素.我也尝试用React组件传递参数,但它似乎不起作用:

createMarker: function() {
  
  /** Some other lines of code */

  var _this = this;

  google.maps.event.addListener(marker, 'click', function() {

    infowindow.setContent( _this._renderInfoWindow(place) );
    infowindow.open(map, _this);

  });

},

// my infowindow rendering method
_renderInfoWindow: function(place) {
  return(
    <div>
      <h4>{place.name}</h4>
      <p>{place.cost}</p>
      <button className="btn btn-danger btn-block" onClick={this.props.addList.bind(this, place)}>I want to go here !! </button>
    </div>
  )
},
Run Code Online (Sandbox Code Playgroud)

那么还有另一种方法来至少将react组件转换为HTML,这样我就不必document.createElement()逐个编写了吗?

谢谢

Ale*_*erg 19

您可以通过分离的DOM节点渲染ReactElement React.render.因此,以下代码应该适合您.

createMarker: function() {

  /** Some other lines of code */

  _this = this;

  google.maps.event.addListener(marker, 'click', function() {

    var div = document.createElement('div');
    ReactDOM.render( _this._renderInfoWindow(place), div );
    infowindow.setContent( div );
    infowindow.open(map, this);

  });

},
Run Code Online (Sandbox Code Playgroud)


Fed*_*ico 9

您也可以使用React的renderToString()方法

_renderInfoWindow: function(place) {
  return React.renderToString(
    <div>
      <h4>{place.name}</h4>
      <p>{place.cost}</p>
      <button className="btn btn-danger btn-block" onClick={this.props.addList.bind(this, place)}>I want to go here !! </button>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

这应该适用于如图所示的简单组件.React.renderToString()将仅返回组件的html.

  • 我使用'react-dom/server'和`ReactDOMServer.renderToStaticMarkup'中的`import ReactDOMServer` (8认同)
  • 使用此方法按钮事件处理程序不起作用。 (3认同)

Yoa*_*ler 7

对于较新版本的 React

import ReactDOMServer from "react-dom/server";

let html = ReactDOMServer.renderToString(<div>...</div>)
Run Code Online (Sandbox Code Playgroud)


小智 7

这就是 React 18 中应该如何完成的:

import { createRoot } from 'react-dom/client';
import { flushSync } from 'react-dom';

const div = document.createElement('div');
const root = createRoot(div);
flushSync(() => {
  root.render(<MyIcon />);
});
console.log(div.innerHTML); // For example, "<svg>...</svg>"
Run Code Online (Sandbox Code Playgroud)

我在尝试迁移到 React 18 时缺少的主要部分是该flushSync部分。在添加它之前我innerHtml总是返回空字符串。

根据这篇文章:https://react.dev/reference/react-dom/server/renderToString#removing-rendertostring-from-the-client-code

必须调用flushSync,以便在读取其innerHTML 属性之前更新DOM。

另外,仍然不建议renderToString导入到浏览器中。react-dom/server