programing

React가 DOM을 직접 관리하지 않는 지역에서는 브라우저에서 ReactDOMServer.renderToString을 사용해도 됩니까?

subpage 2023. 3. 5. 09:47
반응형

React가 DOM을 직접 관리하지 않는 지역에서는 브라우저에서 ReactDOMServer.renderToString을 사용해도 됩니까?

리액트 리플릿을 사용하여 앱 작업을 하고 있습니다.리플릿은 DOM을 직접 조작합니다.리액트 리플릿 라이브러리는 이를 변경하지 않고 리액트 친화적인 방법으로 리액트 맵을 제어하는 데 사용할 수 있는 리액트 컴포넌트를 제공합니다.

이 앱에서는 몇 가지 간단한 요소가 포함된 div인 커스텀 맵마커를 사용하고 싶습니다.리플릿에서 그렇게 하는 방법은 마커를 설정하는 것입니다.icon커스텀 HTML을 설정할 수 있는 DivIcon의 속성을 설정합니다.htmlHTML을 포함하는 문자열에 속성을 지정합니다. 내 경우, 이 HTML을 React 구성 요소에서 렌더링해야 합니다.

그러기 위해서는, 올바른 접근법은 다음과 같이 사용하는 것 같습니다.ReactDOMServer.renderToString()맵 마커 내에서 원하는 컴포넌트를 문자열로 렌더링합니다.이 문자열은 다음과 같습니다.htmlDivIcon 속성:

MyMarker.js:

import React, { Component } from 'react'
import { renderToString } from 'react-dom/server'
import { Marker } from 'react-leaflet'
import { divIcon } from 'leaflet'

import MarkerContents from './MarkerContents'

export class MyMarker extends Component {
  render() {
    const markerContents = renderToString(<MarkerContents data={this.props.data} />)
    const myDivIcon = divIcon({
      className: 'my-marker',
      html: markerContents
    })

    return (
      <Marker
        position={this.props.position}
        icon={myDivIcon} />
    )
  }
}

, React 문서에 따르면 다음과 같습니다.

이 [renderToString]는 서버에서만 사용해야 합니다.

이것은 엄격한 규칙입니까, 아니면 사람들이 React DOM의 효율적인 DOM 관리를 회피하는 것을 막기 위한 것입니까?

내가 추구하는 것을 성취할 수 있는 다른 방법이 생각나지 않는다.어떤 의견이나 아이디어라도 주시면 감사하겠습니다.

새로운 매뉴얼에 따르면 https://reactjs.org/docs/react-dom-server.html

서버 환경과 브라우저 환경 모두에서 다음 방법을 사용할 수 있습니다.

  • renderToString()
  • renderToStaticMarkup()

너무 오래된 질문인 것은 알지만, 아직 답변이 오지 않았기 때문에 제 생각을 공유하고 싶었습니다.

저도 같은 걸 쓰고 있었는데renderToString단, 매뉴얼에서는 클라이언트 측에서 사용하지 않도록 권장하고 있기 때문에 다른 방법으로 이 기능을 구현했습니다.react-domrender사용자 정의 구성 요소를 div로 렌더링하는 방법

var myDiv = document.createElement('div');

ReactDOM.render(
  <MarkerContents data={this.props.data} />,
  myDiv
);

var myIcon = L.divIcon({ 
    iconSize: new L.Point(50, 50), 
    html: myDiv.innerHTML
});

토마스가 이미 말했듯, 그래, 넌 그걸 사용할 수 있어.renderToString클라이언트에 있습니다.다만, 확실히 하기 위해서, 수입할 필요가 있습니다.ReactDOMServer직관에 반하는 것처럼 보일 수 있지만 올바른 것으로 보입니다.예(클라이언트):

import React from 'react';
import ReactDOMServer from 'react-dom/server';

const MyComp = (props) => {
  const html = ReactDOMServer.renderToString(<div>{someFunc(props)}</div>);
  // do something with your html, then
  return <div dangerouslySetInnerHTML={{__html: html}}></div>;
};

나는 전단에서도 똑같은 문제를 겪었고 결국 포털을 통해 문제를 해결했다.

import React, { useEffect, useMemo,useState } from "react";
import ReactDOM from "react-dom";
import { useLeafletContext } from "@react-leaflet/core";
import * as L from "leaflet";

/**
 * @type { React.FC<{
 *    positionX?: number
 *    positionY?: number
 *    width?: number
 *    height?:number
 * }> }
 * */
const LeafletChild = ({ children, positionX=0, positionY=0, width, height }) => {
  const context = useLeafletContext();
  const [divElement] = useState(() => document.createElement("div"));
  const icon = useMemo(() => L.divIcon({ iconSize: new L.Point(height, width), html: divElement }), [height,width, divElement]);
  const marker = useMemo(() => L.marker([0,0], { icon }), [icon]);
  useEffect(()=>{
    marker.setLatLng([positionY, positionX])
  },[positionY,positionX, marker])

  useEffect(() => {
    const container = context.layerContainer || context.map;
    container.addLayer(marker);
    return () => container.removeLayer(marker);
  }, [context, marker]);
  return ReactDOM.createPortal(children, divElement);
};

또 어디...

<LeafletChild>
  <div onClick={()=>setSomeBool(!someBool)}>
    anything you want here like...{`${someBool}`}
  </div>
</LeafletChild>

언급URL : https://stackoverflow.com/questions/37079847/is-it-ok-to-use-reactdomserver-rendertostring-in-the-browser-in-areas-where-reac

반응형