Ich habe mit React herumgespielt und bis jetzt mag ich es wirklich. Ich erstelle eine App mit NodeJS und möchte React für einige der interaktiven Komponenten in der gesamten Anwendung verwenden. Ich möchte es nicht zu einer einseitigen App machen.

Ich habe noch nichts im Internet gefunden, das die folgenden Fragen beantwortet:

Wie kann ich meine React-Komponenten in einer mehrseitigen App aufteilen oder bündeln?

Derzeit befinden sich alle meine Komponenten in einer Datei, obwohl ich sie in einigen Abschnitten der App möglicherweise nie laden werde.

Bisher versuche ich, bedingte Anweisungen zum Rendern von Komponenten zu verwenden, indem ich nach der ID des Containers suche, in dem React gerendert wird. Ich bin mir nicht 100% sicher, welche Best Practices bei React angewendet werden. Es sieht ungefähr so aus.

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

Ich lese immer noch die Dokumentation und habe noch nicht gefunden, was ich für eine mehrseitige App benötige.

Danke im Voraus.

136
Jose Carrillo 11 Aug. 2015 im 07:41

6 Antworten

Beste Antwort

Derzeit mache ich etwas Ähnliches.

Die Anwendung ist keine vollständige React-App. Ich verwende React für dynamische Inhalte wie CommentBox, die autark ist. Und kann an jedem Punkt mit speziellen Parametern aufgenommen werden.

Alle meine Unter-Apps werden jedoch geladen und in eine einzelne Datei all.js aufgenommen, sodass sie vom Browser seitenübergreifend zwischengespeichert werden kann.

Wenn ich eine App in die SSR-Vorlagen aufnehmen muss, muss ich nur einen DIV mit der Klasse "__react-root" und einer speziellen ID (den Namen der zu rendernden React-App) einfügen.

Die Logik ist wirklich einfach:

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>

Bearbeiten

Da Webpack Code-Splitting und LazyLoading perfekt unterstützt, hielt ich es für sinnvoll, ein Beispiel aufzunehmen, in dem Sie nicht alle Ihre Apps in einem Bundle laden müssen, sondern sie aufteilen und bei Bedarf laden müssen.

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);
    });
  }
}
77
webdeb 9 Juli 2018 im 05:49

Verwenden Sie ein CMS? Sie neigen dazu, URLs zu ändern, die Ihre Anwendung beschädigen könnten.

Eine andere Möglichkeit ist die Verwendung von React Habitat.

Damit können Sie Komponenten registrieren und diese werden automatisch dem Dom ausgesetzt.

Beispiel

Komponente (n) registrieren:

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

Dann sind sie in Ihrem Dom wie folgt verfügbar:

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

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

Das Obige wird automatisch durch Ihre Reaktionskomponenten ersetzt.

Sie können dann auch automatisch Eigenschaften (oder Requisiten) an Ihre Komponenten übergeben:

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

Dadurch wird size als Requisite für Ihre Komponente verfügbar gemacht. Es gibt zusätzliche Optionen zum Übergeben anderer Typen wie z als json, Array, Ints, Floats etc.

11
jennas 27 Jän. 2017 im 02:58

Ich weiß, es ist schon eine Weile her, seit diese Frage gestellt wurde, aber hoffentlich hilft das jemandem.

Wie bei @Cocomico erwähnt, können Sie in der Datei webpack.config.js mehrere Einstiegspunkte für die Anwendung angeben. Wenn Sie nach einem einfachen Webpack-Setup suchen (basierend auf der Idee mehrerer Einstiegspunkte), mit dem Sie statischen Seiten React-Komponenten hinzufügen können, sollten Sie Folgendes in Betracht ziehen: https://github.com/przemek-nowicki/multi-page-app-with-react

1
Przemek Nowicki 18 Mai 2019 im 17:22

In der Datei webpack.config.js können Sie mehrere Einstiegspunkte für die Anwendung angeben:

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'
  },
}

Dann können Sie in Ihrem src-Ordner drei verschiedene HTML-Dateien mit ihren jeweiligen js-Dateien haben (Beispiel für Seite 1):

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

JavaScript-Datei:

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

Anschließend können für jede einzelne Seite verschiedene React-Komponenten geladen werden.

50
ekhumoro 16 Nov. 2017 im 17:34

Ich erstelle eine Anwendung von Grund auf und lerne, während ich gehe, aber ich denke, was Sie suchen, ist React-Router. React-Router ordnet Ihre Komponenten bestimmten URLs zu. Beispielsweise:

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)

Im Suchfall ist 'Begriff' als Eigenschaft in der AnimalSearchBox zugänglich:

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

Versuch es. Dieses Tutorial hat mich dazu gebracht übertrieben in Bezug auf mein Verständnis dieses und anderer verwandter Themen.


Die ursprüngliche Antwort folgt:

Ich fand meinen Weg hierher und suchte nach der gleichen Antwort. Überprüfen Sie, ob dieser Beitrag Sie inspiriert. Wenn Ihre Anwendung so etwas wie meine ist, hat sie Bereiche, die sich nur sehr wenig ändern und nur im Hauptteil variieren. Sie können ein Widget erstellen, dessen Aufgabe es ist, basierend auf dem Status der Anwendung ein anderes Widget zu rendern. Mithilfe einer Flussarchitektur können Sie eine Navigationsaktion auslösen, die den Status ändert, in den Ihr Body-Widget wechselt, und nur den Body der Seite effektiv aktualisieren.

Das ist der Ansatz, den ich jetzt versuche.

32
isherwood 11 Okt. 2019 im 13:01

Ich schlage vor, Sie werfen einen Blick auf InertiaJS: https://inertiajs.com/

Mit Inertia erstellen Sie Apps wie immer mit dem serverseitigen Webframework Ihrer Wahl. Sie verwenden die vorhandenen Funktionen Ihres Frameworks für Routing, Controller, Middleware, Authentifizierung, Autorisierung, Datenabruf und mehr.

Das einzige, was anders ist, ist Ihre Ansichtsebene. Anstatt serverseitiges Rendering zu verwenden (z. B. Blade- oder ERB-Vorlagen), sind die Ansichten JavaScript-Seitenkomponenten. Auf diese Weise können Sie Ihr gesamtes Frontend mit React, Vue oder Svelte erstellen.

0
Agu Dondo 12 Feb. 2020 im 22:50