2016-05-06 45 views
17

Pracuję nad aplikacją przy użyciu Leaflet (przez react-leaflet). Ulotka bezpośrednio manipuluje DOM. Biblioteka ulotek reagujących tego nie zmienia, po prostu daje składniki React, które można wykorzystać do kontrolowania mapy ulotek w sposób przyjazny dla reakcji.Czy można używać ReactDOMServer.renderToString w przeglądarce w obszarach, w których React nie zarządza bezpośrednio DOM?

W tej aplikacji chcę użyć niestandardowych znaczników mapy, które są elementami div zawierającymi kilka prostych elementów. Aby to zrobić w ulotce, ustaw właściwość znacznika icon na DivIcon, w której możesz ustawić niestandardowy kod HTML. Ustawisz ten wewnętrzny kod HTML, ustawiając właściwość DivIcon na html na łańcuch zawierający kod HTML. W moim przypadku chcę, aby ten HTML był renderowany ze składnika React.

W tym celu, wydaje się właściwym podejściem jest użycie ReactDOMServer.renderToString() renderować składnik, który chcę wewnątrz znacznika mapy na ciąg znaków, który ja wtedy ustawiony jako własność Divicon html:

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

Jednakże, zgodnie z React docs:

Ten [renderingToString] powinien być używany tylko na serwerze.

Czy jest to surowa zasada, czy też ma ona jedynie na celu zniechęcenie ludzi do obejścia efektywnego zarządzania DOM w ReactDOM?

Nie mogę wymyślić innego (lepszego) sposobu na osiągnięcie tego, co chcę. Wszelkie komentarze i pomysły będą mile widziane.

+0

Nie jestem pewien, czy to będzie pomóc, ale: https://facebook.github.io/react/tips/dangerously-set -inner-html.html i http://stackoverflow.com/questions/21285262/react-leave-the-contents-of-a-component-alone – lux

+0

Dzięki, ale tak naprawdę nie próbuję ręcznie ustawić innerHTML w dowolnym miejscu. Chcę tylko przygotować ciąg HTML z komponentów React, których mogę użyć w folderze DivIcon i zastanawiam się, czy istnieją dobre powody, aby nie używać 'ReactDOMServer.renderToString()', aby to osiągnąć. Zdecydowanie jest to jednak dobre przypomnienie, że należy dbać o higienę HTML. –

+0

Tak, przypuszczam, że to jest przeciwieństwo, co? Jedynym sposobem, w jaki mogłem wyodrębnić czysty HTML z renderingu, jest: http://codepen.io/mikechabot/pen/xVMwgN?editors=0011 Jak widać, jesteśmy w stanie zrzucić ' "

Hello, World.
" 'do konsoli przez' refs', który jest naszym składnikiem, ale musieliśmy podłączyć się do DOM, aby to zrobić. Chciałbym znaleźć twórcę React na Twitterze i przedstawić je bezpośrednio, w przeciwnym razie, dlaczego by nie dać mu strzału? "renderToString()", to znaczy. – lux

Odpowiedz

2

Wiem, że to zbyt stare pytanie, ale ponieważ nie otrzymałem odpowiedzi, chciałem podzielić się moimi przemyśleniami.

używałem samo, renderToString, ale dokumentacja nie zaleca się używać go na stronie klienta, osiągnąłem go w inny sposób, za pomocą render metodę react-dom „s do renderowania komponentu niestandardowego do 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 
}); 
+1

Robiłem to, dopóki React 16 nie zaczął renderować asynchronicznie. Trzeci parametr do "renderowania" musi być funkcją wywołania zwrotnego przed odczytaniem innerHTML, tak jak to: 'ReactDOM.render (component, myDiv,() => console.log (myDiv.innerHTML))' – styfle