Matt Tran Matt Tran - 2 months ago 24
React JSX Question

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/
}
]
}

Answer

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"
    }
}
Comments