2015-08-11 26 views
70

Ho giocato con React e finora mi piace molto. Sto costruendo un'app con NodeJS e vorrei utilizzare React per alcuni dei componenti interattivi attraverso l'applicazione. Non voglio renderlo app a pagina singola.Utilizzo di React in un'app multi-pagina

non ho ancora trovato nulla sul web che rispondere alle seguenti domande:

Come faccio a rompere up o fascio mia Reagire componenti attraverso un multi-pagina di app?

Attualmente tutti i miei componenti sono in un unico file anche se potrei non caricarli mai in alcune sezioni dell'app.

Finora sto cercando di utilizzare le istruzioni condizionali per eseguire il rendering dei componenti cercando l'ID del contenitore in cui React eseguirà il rendering. Non sono sicuro al 100% di quali siano le migliori pratiche con React. Sembra qualcosa del genere.

if(document.getElementById('a-compenent-in-page-1')) { 
    React.render(
     <AnimalBox url="/api/birds" />, 
     document.getElementById('a-compenent-in-page-1') 
    ); 
} 

if(document.getElementById('a-compenent-in-page-2')) { 
    React.render(
     <AnimalBox url="/api/cats" />, 
     document.getElementById('a-compenent-in-page-2') 
    ); 
} 

if(document.getElementById('a-compenent-in-page-3')) { 
    React.render(
     <AnimalSearchBox url="/api/search/:term" />, 
     document.getElementById('a-compenent-in-page-3') 
    ); 
} 

Sto ancora leggendo la documentazione e non ho ancora trovato quello che mi serve ancora per un'applicazione multi pagina.

Grazie in anticipo.

+0

tenta di utilizzare il plugin requirejs. –

+2

Se non ti dispiace che ReactJs sia una libreria JS molto grande che dovrà essere inizializzata per ogni pagina (come hai detto tu non stai costruendo una singola app), allora non sono sicuro che sia importante che tu abbiamo combinato tutti i componenti in un unico file. Sarà memorizzato nella cache sul client. Quando viene caricata una pagina, bisogna renderizzare il componente corretto in un blocco 'script'. – WiredPrairie

+0

Sto riscontrando lo stesso problema: ho un'app che carica altre librerie di grandi dimensioni su pagine diverse e preferisco caricare solo + una libreria in base alle esigenze del visitatore, piuttosto che quattro grandi librerie per ogni evenienza. – AJFarkas

risposta

48

Attualmente, sto facendo qualcosa di simile.

L'applicazione non è una completa App React, sto usando React per cose dinamiche, come CommentBox, che è autark. E può essere incluso in qualsiasi punto con parametri speciali.

Tuttavia, tutte le mie sottospecie sono caricate e incluse in un singolo file all.js, quindi possono essere memorizzate nella cache dal browser tra le pagine.

Quando ho bisogno di includere un App nei modelli SSR, non mi resta che includere un DIV con la classe "__react-root" e un ID speciale, (il nome del Reagire App da rendere)

La logica è molto semplice:

import CommentBox from './apps/CommentBox'; 
import OtherApp from './apps/OtherApp'; 

const APPS = { 
    CommentBox, 
    OtherApp 
}; 

function renderAppInElement(el) { 
    var App = APPS[el.id]; 
    if (!App) return; 

    // get props from elements data attribute, like the post_id 
    const props = Object.assign({}, el.dataset); 

    ReactDOM.render(<App {...props} />, el); 
} 

document 
    .querySelectorAll('.__react-root') 
    .forEach(renderAppInElement) 

<div>Some Article</div> 
<div id="CommentBox" data-post_id="10" class="__react-root"></div> 

<script src="/all.js"></script> 

Cosa ne pensi?

+4

Grazie, penso che questa sia la migliore risposta finora sulla base di ciò di cui avevo bisogno un anno fa. Buon lavoro. Darò una prova la prossima volta. –

+1

Signore, tu sei il maestro, grazie per questo approccio. –

+1

funziona davvero bene, buon lavoro – meda

29

Edit: 11/01/2015

Sto costruendo un'applicazione da zero e sto imparando come vado, ma penso che quello che stai cercando è React-Router. React-Router esegue il mapping dei componenti su URL specifici. Per esempio:

render((
    <Router> 
     <Route path="/" component={App}> 
      <Route path="api/animals" component={Animals}> 
       <Route path="birds" component={Birds}/> 
       <Route path="cats" component={Cats}/> 
      </Route> 
     </Route> 
     <Route path="api/search:term" component={AnimalSearchBox}> 
    </Router> 
), document.body) 

Nel caso di ricerca, 'termine' è accessibile come una proprietà nella AnimalSearchBox:

componentDidMount() { 
    // from the path `/api/search/:term` 
    const term = this.props.params.term 
} 

provarlo. Il tutorial This è quello che mi ha messo al primo posto in termini di comprensione di questo e di altri argomenti correlati.

risposta originale segue:

ho trovato la mia strada qui cercando la stessa risposta. Vedi se il post this ti ispira. Se la tua applicazione è diversa dalla mia, avrà aree che cambiano molto poco e variano solo nel corpo principale. È possibile creare un widget la cui responsabilità è di rendere un widget diverso in base allo stato dell'applicazione. Utilizzando un'architettura di flusso, è possibile inviare un'azione di navigazione che modifica lo stato in cui si attiva il widget del corpo, aggiornando effettivamente solo il corpo della pagina.

Questo è l'approccio che sto tentando ora.

+0

È una risposta completa? – manetsus

+5

Cosa succede se il percorso URL viene creato dal mio codice back-end (nodejs in questo caso)? Il 'Router' funzionerà nello stesso modo in una app singola? –

+0

Grazie per il collegamento nella tua risposta originale. Il post di Tommy Marshall è esattamente ciò di cui ho bisogno. – saawsann

7

Stai utilizzando un CMS? Tendono ad apprezzare gli URL che potrebbero rompere la tua richiesta.

Un altro modo è utilizzare qualcosa come React Habitat.

Con esso, è possibile registrare componenti e vengono automaticamente esposti al dom.

Esempio

componente Register (s):

container.register('AnimalBox', AnimalBox); 
container.register('AnimalSearchBox', AnimalSearchBox); 

allora sono consumata in dom in questo modo:

<div data-component="AnimalBox"></div> 

<div data-component="AnimalSearchBox"></div> 

È possibile che questo verrà sostituito automaticamente con i tuoi componenti reagiscono.

È quindi possibile passare automaticamente le proprietà (o oggetti di scena) per i componenti anche:

<div data-component="AnimalBox" data-prop-size="small"></div> 

Questo esporrà size come un puntello per il componente. Ci sono additional options per passare altri tipi come json, array, ints, float ecc.

13

È possibile fornire diversi punti di ingresso per l'applicazione nel file webpack.config.js:

var config = { 
    entry: { 
    home: path.resolve(__dirname, './src/main'), 
    page1: path.resolve(__dirname, './src/page1'), 
    page2: path.resolve(__dirname, './src/page2'), 
    vendors: ['react'] 
    }, 
output: { 
    path: path.join(__dirname, 'js'), 
    filename: '[name].bundle.js', 
    chunkFilename: '[id].chunk.js' 
    }, 
} 

allora si può avere nella cartella src tre diversi file html con i loro rispettivi file js (esempio per pagina1):

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>Page 1</title> 
</head> 
<body> 
    <div id="app"></div> 
    <script src="./vendors.js"></script> 
    <script src="./page1.bundle.js"></script> 
</body> 
</html> 

file JavaScript:

import React from 'react' 
import ReactDom from 'react-dom' 
import App from './components/App' 
import ComponentA from './components/ReactComponentA' 
ReactDom.render(<div> 
        <App title='page1' /> 
        <ReactComponentA/> 
       </div>, document.getElementById('app')) 

diverso Re i componenti di act possono quindi essere caricati per ogni singola pagina.

+0

La tua risposta si adatta meglio al suo progetto. –

Problemi correlati