6

Ho iniziato a creare un'applicazione isomorfa React/Redux basata su Node. Uno dei requisiti del progetto è il rendering "adattativo" di componenti specifici basati su una vista "mobile" e "desktop". Ho implementato l'azione Redux e il riduttore per archiviare le informazioni sullo schermo relative alla vista dell'utente (basate su query multimediali "piccole", "medie", "grandi") nello stato. Al ridimensionamento lo stato/il negozio viene aggiornato. Lo stato predefinito è "piccolo".React/Redux isomorphic/server-side rendering e media query

const defaultState = { 
    isMobile: true, 
    isTablet: false, 
    isDesktop: false, 
    sizes: { 
     small: true, 
     medium: false, 
     large: false, 
     huge: false, 
    }, 
}; 

Nel componente che deve essere reso "adaptive" in due diverse versioni in base alle dimensioni dello schermo, faccio semplicemente una:

se (piccola) di ritorno variation1

se (media) variazione di ritorno2

Tutto funzionante.

Ora sto affrontando due problemi:

  1. mia app è isomorfo, questo significa che il markup rende anche sul lato server. Il server non sa nulla del browser dell'utente e delle query multimediali. Quindi, poiché il mio stato predefinito è "small", il server render sempre "variation1". Il nodo-server è il punto di ingresso per il sito. Sembra che il rendering debba essere "ritardato" (middleware?) E il server deve recuperare alcune informazioni dal client sulla larghezza del browser prima che l'app React venga "consegnata". Qualche idea su come questo problema possa essere risolto?

  2. perché il rendering si basa sullo stato, dopo che il carico "variazione 1" può essere sempre visto prima per alcuni millisecondi (sfarfallio), anche quando la dimensione del browser è "desktop". Questo perché il rilevamento JS impiega alcuni millisecondi prima che lo stato venga aggiornato con la larghezza dello schermo corrente. Penso che questo funzioni insieme al problema precedente e allo stato predefinito.

Non sono riuscito a trovare alcuna soluzione per 1, ma suppongo che ci deve essere qualcosa di isomorfo E reattivo/adattivo.

+0

Sono curioso di sapere cos'è "variazione1". Non è ancora sicuro se è pertinente alla tua domanda o no, ma la variazione è solo un rendering alternativo della vista, o c'è anche qualcos'altro? –

+0

"Variation 1" e "Variation 2" condividono gli stessi dati, ma la vista sembra diversa e agisce anche in modo diverso. Like 1 è un tipo di fisarmonica e 2 solo un layout statico. Non pertinente alla domanda, penso anch'io. Il problema sopra descritto è più generale. – Krad

risposta

0

È possibile ottenere l'agente utente dall'intestazione sul server, quindi inviare un'azione di ridondanza con le informazioni dell'agente utente con un riduttore che restituisce i dati, in questo modo è possibile rilevare se l'utente su cellulare/tablet/desktop/etc e visualizzare di conseguenza

+0

Sinceramente sento che il dispositivo di rilevamento è insufficiente in questi giorni. È necessario rilevare la risoluzione in quanto i dispositivi stessi hanno risoluzioni così diverse. Tablet anche desktop e computer portatili. – ctrlplusb

+0

@ctrlplusb sì, sono un po 'd'accordo con te sul fatto che ci sono molti dispositivi con risoluzioni diverse, ma a volte con la visualizzazione di desktop, tablet, desktop può essere sufficiente dipende dal caso d'uso – alpha

+0

Sono d'accordo con @ctrlplusb. Potrei annusare il dispositivo, ma questo non è un modo dimostrato dal futuro. Troppi dispositivi là fuori (e altri in futuro). Un requisito è anche quello di "rompere" a 767px. Tutti Krad

5

Un problema molto difficile da risolvere a mio avviso con molte soluzioni basate "dipende". :)

Sono l'autore di react-sizeme e react-component-queries, due librerie che aiutano con componenti reattivi e hanno riscontrato problemi simili a quelli descritti nella domanda. Nella mia esperienza ho scoperto che inventare una soluzione a uno dei tuoi problemi spesso colpisce l'altro. Io dettaglio cosa intendo qui descrivendo la mia esperienza qui sotto ...

avevo cercato di risolvere il tuo "problema 2" primo:

Lo sfarfallio di rendere a causa dello stato di default è stato qualcosa che ho sperimentato durante la mia creazione iniziale della libreria react-sizeme. react-sizeme è un componente di ordine superiore che ottiene la dimensione disponibile per il componente e quindi lo passa nel componente. In base alle dimensioni, puoi ovviamente scegliere di eseguire il rendering di diversi componenti come hai fatto nel tuo esempio, pertanto è possibile che si verifichi lo sfarfallio, a meno che non si verifichi un errore di stato predefinito. Ho "conquistato" questo modificando react-sizeme per il rendering iniziale di un segnaposto vuoto al fine di ottenere la larghezza/altezza disponibile e quindi solo il rendering del componente, dandogli la "corretta" larghezza/altezza. Questo ha funzionato molto efficacemente per me.Non vedo più il rendering di ComponentBob, solo per essere smontato e avere ComponentFoo immediatamente al suo posto.

Poi "Problema 1" è venuto lungo ...

react-sizeme iniziato a guadagnare popolarità e alla fine ho avuto un consumatore della biblioteca che ha voluto utilizzare in un contesto di rendering lato server. Ma a causa della correzione che ho messo in atto per il problema 1, il rendering lato server avrebbe prodotto un sacco di contenuti vuoti (cioè i segnaposto di cui stavo parlando). Dopo che il payload è stato consegnato al browser, la logica del segnaposto si sarebbe attivata e alla fine i dati sulle dimensioni sarebbero stati inviati al componente e sarebbero stati resi. Questo non è l'ideale in quanto, in primo luogo, annullate sostanzialmente qualsiasi vantaggio derivante dal fare SSR. Ho lavorato con questo utente e abbiamo deciso che la soluzione migliore sarebbe quella di consentire a react-sizeme di essere configurato per l'esecuzione in "Modalità SSR". Fondamentalmente questo comportava il rilascio del rendering segnaposto e il rendering di un componente predefinito da rendere in modo da non ottenere pagine vuote sulla risposta iniziale del server, ma in tal caso si può facilmente soffrire nuovamente del problema di sfarfallio del componente!

Aaaaaaaaaah! La sega dell'affetto qui! :(

Quindi, fondamentalmente risolvere un problema colpisce direttamente l'altra.


ho continuato a dare a questo qualche pensiero e credo che probabilmente il modo migliore per farlo è quello di cercare di ottenere gli utenti larghezza/altezza del browser alla prima richiesta Ciò significherebbe essenzialmente il rendering di una semplice utility che pesca queste informazioni e la reinserisce sul server con l'intenzione di rendere la richiesta iniziale dell'utente. Potresti quindi utilizzare la larghezza/altezza e passarla attraverso l'intero albero dei componenti (facendo matematica lungo la strada) per continuare a determinare quale sia l'altezza/larghezza disponibile per ogni componente, materiale superintelligente qui, ma che potrebbe funzionare.

L'altro pericolo è che google semplicemente indicizza una pagina vuota per la richiesta iniziale (ad es. il rendering vuoto dell'utilità che pesca la larghezza/altezza iniziale). Dovresti provare a utilizzare alcuni codici di risposta HTTP intelligenti, come i reindirizzamenti, ecc. Per assicurarti che google segua il percorso verso l'output di rendering corretto.


spiace, ma questo non può essere la risposta che stavate cercando, ma spero che la mia esperienza aiuta in qualche modo o fornisce un qualche tipo di ispirazione. Se trovi qualche esperimento interessante, tienimi aggiornato. Sarei felice di lavorare con voi su questo.

+1

Grazie per la risposta @ctrlplusb. Sembra un problema serio per me. Il motivo per cui eseguo il rendering sul server è SEO. Poiché il contenuto è lo stesso su "mobile" e "desktop", nel mio caso non ha importanza quale versione legge un crawler. La "modalità SSR" che hai descritto è fondamentalmente ciò che ho ora, uno stato predefinito, che viene fornito con lo sfarfallio.L'idea di utilizzare una sorta di middleware tra server-hit e react-rendering suona un po 'complicato e significherebbe anche un'ulteriore richiesta (rallentamento delle prestazioni). Ti tengo aggiornato qui nel caso trovassi una soluzione alternativa. – Krad

+0

Proprio per la cronaca, al momento non ho molto tempo per capire una soluzione per il problema precedente, quindi sono andato su 'mobile-detect.js' sul server e ho passato le informazioni dell'intestazione allo stato. In questo modo non posso adattarmi di una larghezza specifica, ma la mia gente qui è contenta che funzioni così. – Krad

+0

Non sono un esperto SEO, ma per me la soluzione a sfarfallio non è una soluzione, non penso che i crawler (che leggono js anche in questi giorni ..), siano così felici di vedere un contenuto per un istante e un altro contenuto dopo ... – cl0udw4lk3r