React'i çok sayfalı bir uygulamada kullanma


122

React ile oynuyordum ve şimdiye kadar gerçekten beğendim. NodeJS ile bir uygulama geliştiriyorum ve uygulamadaki bazı etkileşimli bileşenler için React'i kullanmak istiyorum. Tek sayfalık uygulama yapmak istemiyorum.

Henüz web'de aşağıdaki soruları yanıtlayan bir şey bulamadım:

React bileşenlerimi çok sayfalı bir uygulamada nasıl ayırabilirim veya paketleyebilirim?

Şu anda tüm bileşenlerim tek bir dosyadadır, ancak bunları uygulamanın bazı bölümlerine asla yüklemeyebilirim.

Şimdiye kadar, React'in işleyeceği konteynerin kimliğini arayarak bileşenleri işlemek için koşullu ifadeler kullanmaya çalışıyorum. React ile en iyi uygulamaların ne olduğundan% 100 emin değilim. Bunun gibi bir şeye benziyor.

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

Hala belgeleri okuyorum ve çok sayfalı bir uygulama için ihtiyacım olanı henüz bulamadım.

Şimdiden teşekkürler.


requirejs eklentisini kullanmayı deneyin.
amit_183

2
ReactJs'in her sayfa için başlatılması gereken çok büyük bir JS kitaplığı olması sizin için bir sakınca yoksa (tek sayfalık bir uygulama oluşturmadığınızı söylediğiniz gibi), o zaman sizin için önemli olup olmadığından emin değilim ' tüm bileşenleri tek bir dosyada birleştirdik. İstemcide önbelleğe alınacaktır. Bir sayfa yüklendiğinde, renderbir scriptblokta doğru bileşene sahip olun .
WiredPrairie

Aynı sorunu yaşıyorum: Diğer büyük kitaplıkları farklı sayfalara yükleyen bir uygulamam var ve her ihtimale karşı dört büyük kitaplık yerine react + bir kitaplığı ziyaretçinin ihtiyaçlarına göre yüklemeyi tercih ederim.
AJFarkas

Yanıtlar:


83

Şu anda benzer bir şey yapıyorum.

Uygulama tam bir React Uygulaması değil, React'i autark olan CommentBox gibi dinamik Şeyler için kullanıyorum. Ve özel parametrelerle herhangi bir Noktaya dahil edilebilir ..

Ancak, tüm alt Uygulamalarım yüklenir ve tek bir dosyaya dahil edilir all.js, böylece tarayıcı tarafından sayfalar arasında önbelleğe alınabilir.

SSR Şablonlarına bir Uygulama eklemem gerektiğinde, sadece "__react-root" sınıfına sahip bir DIV ve özel bir kimlik (işlenecek React Uygulamasının adı) eklemem gerekiyor.

Mantık gerçekten çok basit:

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>

Düzenle

Webpack, kod bölmeyi ve LazyLoading'i mükemmel şekilde desteklediğinden, tüm uygulamalarınızı tek bir pakette yüklemeniz gerekmeyen, ancak bunları ayırıp talep üzerine yüklemeniz gereken bir örnek eklemenin mantıklı olduğunu düşündüm.

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

1
Harika görünüyor, npm create-react-app kullanırken bunu çalıştıran var mı? Bunun benim için işe yarayacağını sanmıyorum ... Şu anda 1 uygulamasıyla çalıştırıyorum ve nasıl çalıştığını görebiliyorum, ancak yapım doğru çalışan bir üretim yapısı oluşturmayacak.
Sprose

@Sprose, create-react-app ile de çalışmalı, bir şey mi eksik? Belki github'da olmadığı yerde küçük bir örnek paylaşabilirsiniz, olmaması için bir neden göremiyorum
webdeb

1
@Sprose geç cevap için üzgünüm, ama bence tamamen farklı bir şey deniyorsun, bu yaklaşım neyi çözmeye çalışıyor. IMO create react app, yaratmanız için size bazı kolay araçlar sunar bundle.js. Dolayısıyla, cevabımın amacı aynı şeyi kullanmak bundle.jsve birden fazla SSR sitesinde kullanmak ve birçok farklı React uygulamasını tek bir sayfaya yüklemek. Üzgünüm, cevabım ihtiyaçlarınıza uymuyorsa, yeni bir Gönderi oluşturmaktan ve ne yapmaya çalıştığınızı açıklamaktan çekinmeyin, size yardımcı olmaya çalışırdım.
webdeb

1
@SorcererApprentice cra web paketini kullanır, webpack.js.org/guides/getting-started/#creating-a-bundle
webdeb

1
@SorcererApprentice temelde birisi web paketi yapılandırmasını bu sayfada yayınladı: stackoverflow.com/a/41857199/5004923
webdeb

52

Webpack.config.js dosyasında uygulama için birkaç giriş noktası sağlayabilirsiniz:

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

daha sonra src klasörünüzde ilgili js dosyalarıyla birlikte üç farklı html dosyasına sahip olabilirsiniz (örneğin page1 için):

<!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 dosyası:

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

Daha sonra her bir sayfa için farklı React bileşenleri yüklenebilir.


1
Aşağıdakileri webex sayfasında okudum. webpack version < 4 it was common to add vendors as separate entrypoint to compile it as separate file (in combination with the CommonsChunkPlugin). This is discouraged in webpack 4. Instead the optimization.splitChunks option takes care of separating vendors and app modules and creating a separate file. Do not create a entry for vendors or other stuff which is not the starting point of execution.Öyleyse, bu örnek webpack 4+ için güncellenmeli mi?
Ramesh

32

Sıfırdan bir uygulama geliştiriyorum ve ilerledikçe öğreniyorum, ama bence aradığınız şey React-Router . React-Router, bileşenlerinizi belirli URL'lerle eşler. Örneğin:

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)

Arama durumunda, 'terim' AnimalSearchBox'ta bir özellik olarak erişilebilir:

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

Denemek. Bu öğretici, bu ve diğer ilgili konuları anlamam açısından beni en üst sıralara çıkaran eğitimdir.


Orijinal cevap şöyledir:

Burada aynı cevabı ararken yolumu buldum. Bu gönderinin size ilham verip vermediğini görün . Başvurunuz benimki gibi bir şey ise, çok az değişen ve sadece ana gövdede değişen alanlara sahip olacaktır. Uygulamanın durumuna bağlı olarak farklı bir pencere öğesi oluşturma sorumluluğu olan bir pencere öğesi oluşturabilirsiniz. Bir akı mimarisi kullanarak, gövde widget'inizin devreye girdiği durumu değiştiren ve yalnızca sayfanın gövdesini etkili bir şekilde güncelleyen bir gezinme eylemi gönderebilirsiniz.

Şimdi denediğim yaklaşım bu.


8
URL yolu arka uç kodum (bu durumda nodejs) tarafından oluşturulmuşsa ne olur? Will Routerçalışma tek sayfa uygulama yok aynı şekilde?
Jose Carrillo

1
@Scott Özel widget'lara sahip yönetici sayfası işlevselliğini ortaya çıkarmak istemezsem ne olur? React'i kullanarak gerçek kimlik doğrulaması olmadan görünümü ve hissi yeniden yaratmak mümkündür.
Kairat Kempirbaev

11

Bir CMS kullanıyor musunuz? Uygulamanızı bozabilecek url'leri değiştirme eğilimindedirler.

Başka bir yol da React Habitat gibi bir şey kullanmaktır .

Bununla birlikte, bileşenleri kaydettirebilirsiniz ve bunlar otomatik olarak doma açılır.

Misal

Bileşenleri kaydedin:

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

Öyleyse sizin domunuzda şu şekilde kullanılabilirler:

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

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

Yukarıdakiler otomatik olarak react bileşenlerinizle değiştirilecektir.

Daha sonra, bileşenlerinize de otomatik olarak özellikleri (veya propları) aktarabilirsiniz:

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

Bu, sizebileşeninize bir destek olarak ortaya çıkacaktır . Json, array, ints, floats vb. Gibi diğer türleri geçirmek için ek seçenekler vardır .


2

Bu sorunun sorulmasının üzerinden epey zaman geçtiğini biliyorum ama umarım bu birine yardımcı olur.

@Cocomico'nun bahsettiği gibi, webpack.config.js dosyasında uygulama için birkaç giriş noktası sağlayabilirsiniz. Statik sayfalara React bileşenleri eklemenize izin veren basit bir Web paketi kurulumu (birden fazla giriş noktası fikrine dayalı olarak) arıyorsanız, bunu kullanmayı düşünebilirsiniz: https://github.com/przemek-nowicki/multi-page -app-ile-tepkimeye


-1

InertiaJS'ye bir göz atmanızı öneririm: https://inertiajs.com/

Atalet ile, tercih ettiğiniz sunucu tarafı web çerçevesiyle her zaman yaptığınız gibi uygulamalar geliştirirsiniz. Çerçevenizin mevcut işlevselliğini yönlendirme, denetleyiciler, ara yazılım, kimlik doğrulama, yetkilendirme, veri getirme ve daha fazlası için kullanırsınız.

Farklı olan tek şey, görüş katmanınızdır. Sunucu tarafı oluşturma (örneğin, Blade veya ERB şablonları) kullanmak yerine, görünümler JavaScript sayfası bileşenleridir. Bu, tüm ön ucunuzu React, Vue veya Svelte kullanarak oluşturmanıza olanak tanır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.