Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS: How to have multiple SPA's on the same website

I'm creating an Airbnb clone.

I noticed if I made the whole website one SPA then my nested routes would be a huge mess. I wanted to make each tab it's own SPA, but ran into errors when trying to create multiple SPAs.

What I did was create an App component and then rendered it to the Index.html, that worked!

But when I created a BecomeAHost component, and tried to render it to BecomeAHost.html (a different page) I got an error:

bundle.js:886 Uncaught Invariant Violation: _registerComponent(...):
Target container is not a DOM element.

My main question is: How do I have multiple ReactJS single page applications on the same website so I don't have about 30 routes all nested together?

Here is the Github repo: https://github.com/strangebnb/template

Here is the 2nd component that I'm trying to render on a BecomeAHost.html

import React, { PropTypes } from 'react'
import ReactDOM from 'react-dom';
import {Component} from 'react';
import { Router, Route, Link, IndexRoute, hashHistory, DefaultRoute, IndexLink, browserHistory } from 'react-router'

import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import {RadioButton, RadioButtonGroup} from 'material-ui/RadioButton';
import ActionFavorite from 'material-ui/svg-icons/action/favorite';
import ActionFavoriteBorder from 'material-ui/svg-icons/action/favorite-border';

const styles = {
  block: {
    maxWidth: 250,
  },
  radioButton: {
    marginBottom: 16,
  },
};


const BecomeAHost = React.createClass ({
  render() {
    return(
      <MuiThemeProvider>
        <div>
          <First/>
        </div>
      </MuiThemeProvider>
    )
  }
})

const First = () => (
  <div>
    <h1>Become an Airbnb host</h1>
    <p>Start off by creating a listing page. Think of it as a profile page for your place.</p>
    <br></br>
    <p>Step 1</p>
    <h3>Start with the basics</h3>
    <h4>Beds, bathrooms, amenities, and more</h4>
  </div>
)

ReactDOM.render(<BecomeAHost />, document.getElementById('host'));

Here is how I'm trying to render it on the page

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Template</title>
    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
  </head>
  <body>
    <div id='host'>Loading...</div>
    <script src='./bundle/bundle.js' type="text/javascript"></script>
  </body>
</html>

I think the error may be that my webpack is configured to only handle my main App (my main App on Index.html does work). Here is my webpack

var webpack = require('webpack');
var path = require('path');

module.exports = {
    entry: {
        main: "./src/App.js"
    },
    output: {
        path: "./public",
        filename: "/bundle/bundle.js"
    },
    devtools: "sourcemap",
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                loader: "babel"
            },
      {
        test: /\.scss$/,
        loaders:  ["style", "css", "sass"],
        exclude: /node_modules/
      }
        ]
    }
like image 826
Matt Tran Avatar asked Sep 04 '16 06:09

Matt Tran


People also ask

Can you build an MPA with react?

As we discussed above, we have many libraries and frameworks that we can use when building MPAs. However, in my opinion, React or Vue. js would be the best to build an MPA for the following reasons. Both are lightweight and fast.

Is nextJS SPA or MPA?

nextJS only support a special case to statically back the html pages, but even if you statically generates it, it's still a SPA :) Anyway, if you need to insert react multiple times to another html, just do ReactDOM.

Is react JS SPA or MPA?

SPAs are reactive web applications that give a native look and feel without page loads. SPAs owe this to AJAX/Client-Side Rendering typically provided by a client-side framework such as react/vue/angular. Many in the industry refer to more traditional web applications as Multi-Page Applications (MPAs).


1 Answers

That's because both of your pages loads the same bundle, it will never find both the app and the host DOM elements to render correctly. Try using webpack's multiple entry points and then require them separately in each .html:

{
    entry: {
        a: "./a",
        b: "./b",
        c: ["./c", "./d"]
    },
    output: {
        path: path.join(__dirname, "dist"),
        filename: "[name].entry.js"
    }
}
like image 62
martriay Avatar answered Nov 02 '22 01:11

martriay