Pytanie Stabilny reaktywny dla renderowania po stronie serwera


Używając przycisku React do renderowania komponentów na serwerze, zauważam, że atrybuty reagid danych są efektywnie losowe. Rozumiem, że się tego oczekuje. (https://groups.google.com/forum/#!topic/reactjs/ewTN-WOP1w8)

Jednak trochę zaskakujące jest to, że w przeciwnym razie funkcjonalne ramy wprowadzają taki niedeterminizm do obrazu wyjściowego. Oznacza to, że kolejne renderowanie widoku o identycznym stanie spowoduje utworzenie innego HTML, co zapobiegnie na przykład zwróceniu przez mechanizm widokowy wartości "304 Not Modified" lub wygenerowaniu wiarygodnego ETag. (Doceniam, że takie buforowanie może być obsługiwane również na wyższej warstwie infrastruktury.)

Czy istnieje sposób na zaszczepienie generowania identyfikatora, aby reaktywne były deterministyczne? Czy powodem jest zły pomysł wyjaśniony gdzie indziej?


12
2018-02-15 02:55


pochodzenie




Odpowiedzi:


W końcowym komentarzu do Wątek grupy Google Ben Alpert mówi:

W przypadku renderowania serwera ważne jest, aby różne renderowane komponenty nie miały kolidujących identyfikatorów (nawet jeśli są renderowane na różnych serwerach, na przykład), więc wybieramy je losowo.


3
2018-02-17 22:00



Inne, niż powiedzenie "to jest ważne", nie jest jasne, dlaczego tak jest. - Sebastian Good
Przeczytałem jego komentarz, ponieważ powodem, dla którego React używa losowych identyfikatorów, jest to, że komponenty nie mogą mieć kolidujących identyfikatorów, nawet na różnych serwerach. Niektórzy mówią o zmianie w jaki sposób tworzone są losowe identyfikatory w Github i możesz podążać za ich tropem, aby wygenerować własne identyfikatory, jeśli chcesz. - Brett DeWoody


Niedawno o tym pomyślałem (po prostu zaczęło używać reactjs),

Możliwe rozwiązanie jest dość proste - nie ma wymogu generowania ETag z prawdziwego html ... - może być generowany z wyświetlanych danych.

Możesz więc wygenerować go z wirtualnego domu - po prostu użyj React.renderComponentToStaticMarkup(…) i wygeneruj z niego ETag ...

Lub możesz usunąć wszystkie reaktywne z renderowanego html za pomocą regexp przed spopielaniem (prawdopodobnie szybciej niż oddzielnym renderowaniem) ...

W przypadku korzystania z ekspresu będzie to coś takiego:

var virtualDom = React.createFactory(Handler)({});
var html = React.renderToString(virtualDom);

var etag = app.get('etag fn');
if (etag) {
  etag = etag(React.renderComponentToStaticMarkup(virtualDom), 'utf8');
  etag && res.set('ETag', etag);
}

res.render( ... );

1
2018-02-22 07:38





To też mnie nękało, więc zacząłem się zastanawiać, co by się stało, gdybym zdecydował się na reaktywność root'a.

Możliwe jest nadpisanie tego w Reagowaniu 0.14.x, jeśli jesteś gotów pogodzić się z następującym hackowaniem. W pliku po stronie serwera, na który wywołujesz ReactDOM.renderToString, umieść to u góry:

// Override the ServerReactRootIndex.createReactRootIndex function
var ServerReactRootIndex = require('react/lib/ServerReactRootIndex');
ServerReactRootIndex.createReactRootIndex = function(){
    return "x"; // Results in an attribute like data-reactid=".x"
};

// Use React as usual
// NB: require('react') must come AFTER overriding ServerReactRootIndex.createReactRootIndex
var React = require('react');

To nie jest częścią interfejsu API React, więc może się on rozpaść w najbliższej przyszłości. Działa to jednak teraz, jeśli absolutnie tego potrzebujesz. Powoduje to również, że atrybut check-react-suma kontrolna staje się stabilny dla tego samego renderowanego DOM.

Jeśli masz wiele komponentów React root na jednej stronie, MUSZĄ mieć różne identyfikatory root, więc będziesz musiał zmodyfikować tę funkcję, aby to uwzględnić.


0
2017-11-08 12:46