web-dev-qa-db-fra.com

Utilisation de React dans une application multipage

J'ai joué avec React et jusqu'à présent, je l'aime vraiment beaucoup. Je construis actuellement une application avec NodeJS et souhaiterais utiliser React pour certains des composants interactifs de l'application. Je ne veux pas en faire une seule page.

Je n'ai encore rien trouvé sur le Web qui réponde aux questions suivantes:

Comment briser ou regrouper mes React composants dans une application de plusieurs pages?

Actuellement, tous mes composants sont dans un seul fichier, même si je ne peux jamais les charger dans certaines sections de l'application.

Jusqu'à présent, j'essaie d'utiliser des instructions conditionnelles pour rendre les composants en recherchant l'ID du conteneur où React sera rendu. Je ne suis pas sûr à 100% des meilleures pratiques avec React. Cela ressemble à quelque chose comme ça.

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')
    );
}

Je suis toujours en train de lire la documentation et je n'ai pas encore trouvé ce dont j'avais besoin pour une application de plusieurs pages.

Merci d'avance.

105
Jose Carrillo

Actuellement, je fais quelque chose de similaire.

L'application n'est pas une application complète React, j'utilise React pour des commandes dynamiques, comme CommentBox, qui est autark. Et peut être inclus à tout moment avec des paramètres spéciaux.

Cependant, toutes mes sous-applications sont chargées et incluses dans un seul fichier all.js _, de sorte qu'il peut être mis en cache par le navigateur sur plusieurs pages.

Lorsque j'ai besoin d'inclure une application dans les modèles SSR, il me suffit d'inclure une DIV avec la classe "__react-root" et un identifiant spécial (le nom de l'application React à restituer).

La logique est vraiment simple:

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>

Modifier

Étant donné que Webpack prend parfaitement en charge le fractionnement de code et le LazyLoading, j’ai pensé qu’il était judicieux d’inclure un exemple dans lequel vous n’avez pas besoin de charger toutes vos applications dans un seul paquet, mais de les scinder et de les charger à la demande.

import React from 'react';
import ReactDOM from 'react-dom';

const apps = {
  'One': () => import('./One'),
  'Two': () => import('./Two'),
}

const renderAppInElement = (el) => {
  if (apps[el.id])  {
    apps[el.id]().then((App) => {
      ReactDOM.render(<App {...el.dataset} />, el);
    });
  }
}
74
webdeb

Vous pouvez fournir plusieurs points d'entrée pour l'application dans le fichier 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'
  },
}

alors vous pouvez avoir dans votre dossier src trois fichiers html différents avec leurs fichiers js respectifs (exemple pour la page1):

<!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>

Fichier 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'))

Différents composants React peuvent ensuite être chargés pour chaque page.

48
Cocomico

Edit: 11/01/2015

Je construis une application à partir de la base et j'apprends au fur et à mesure, mais je pense que ce que vous recherchez est React-Router . React-Router mappe vos composants sur des URL spécifiques. Par exemple:

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)

Dans le cas de recherche, le terme "terme" est accessible en tant que propriété dans AnimalSearchBox:

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

Essaye le. Ce tutoriel est celui qui m'a mis au dessus en termes de compréhension de ce sujet et d'autres sujets connexes.

La réponse originale suit:

J'ai trouvé mon chemin ici en cherchant la même réponse. Voyez si ceci post vous inspire. Si votre application ressemble à la mienne, elle aura des zones qui changent très peu et ne varient que dans le corps principal. Vous pouvez créer un widget chargé de rendre un widget différent en fonction de l'état de l'application. En utilisant une architecture de flux, vous pouvez envoyer une action de navigation qui modifie l'état sur lequel bascule le widget corps, mettant à jour efficacement le corps de la page uniquement.

C'est l'approche que je tente maintenant.

32
Scott

Utilisez-vous un CMS? Ils ont tendance à aimer changer les URL qui pourraient casser votre application.

Une autre façon consiste à utiliser quelque chose comme React Habitat .

Avec celui-ci, vous pouvez enregistrer des composants et ils sont automatiquement exposés au dom.

Exemple

Enregistrer le (s) composant (s):

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

Ensuite, ils sont disponibles dans votre domaine comme ceci:

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

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

Ce qui précède sera automatiquement remplacé par vos composants de réaction.

Vous pouvez ensuite transmettre automatiquement les propriétés (ou les accessoires) à vos composants:

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

Cela exposera size comme accessoire de votre composant. Il y a options supplémentaires pour passer d'autres types tels que json, array's, ints, floats, etc.

11
jennas

Je sais que cette question a été posée il y a longtemps, mais j'espère que cela aidera quelqu'un.

Comme @Cocomico l'a mentionné, vous pouvez fournir plusieurs points d'entrée pour l'application dans le fichier webpack.config.js. Si vous recherchez une configuration Webpack simple (basée sur l'idée de plusieurs points d'entrée) vous permettant d'ajouter des composants React à des pages statiques, vous pouvez envisager d'utiliser ceci: https: // github .com/przemek-nowicki/multi-page-app-with-react

1
Przemek Nowicki