React router cannot GET any specified routes, except the root / - reactjs

Here's my App.jsx that's first mounted to the DOM:
import React, { Component } from 'react';
import Home from './Home.jsx';
import Representatives from './Representatives.jsx';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
export default class App extends Component {
constructor() {
super();
this.state = {value: ''};
}
render() {
return (
<Router>
<div>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/representatives" component={Representatives} />
</Switch>
</div>
</Router>
)
}
}
And here's the representative's component:
import React, { Component } from 'react';
export default class Representatives extends Component {
constructor() {
super();
this.state = {value: ''};
}
render() {
return (
<div>
Hello World!
</div>
)
}
}
It looks exactly like examples I've seen and my webpack config looks like other's I've seen in similar posts. Any help would be greatly appreciated, I'm at 4+ hours wracking my brain
Here's my webpack config:
const path = require('path');
const SRC_DIR = path.resolve(__dirname, './src');
const BUILD_DIR = path.resolve(__dirname, './public/');
module.exports = {
mode: 'development',
entry: path.resolve(SRC_DIR, 'index.jsx'),
output: {
filename: 'bundle.js',
path: BUILD_DIR,
publicPath: '/'
},
devServer: {
historyApiFallback: true,
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: [/node_modules/],
use: [{
loader: 'babel-loader',
options: { "presets": [
"#babel/env",
"#babel/react"
] }
}],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
]
}
}
I added the historyApiFallback: true, and publicPath: '/'
as recommended by another post here.
Here is the index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App/App.jsx';
ReactDOM.render(<App />, document.getElementById('root'));

Related

React Router with deeper paths

I am trying to get an example with React Router running.
My example has the 3 following routes:
(works in browser) http://0.0.0.0:8081/one
(fails in browser) http://0.0.0.0:8081/one/two
(fails in browser) http://0.0.0.0:8081/one/two/three
All routes work with Link, but only 1. works when typing the url in the browser. When typing i.e. the 2. route in the browser, the browser console responds the following error:
GET http://0.0.0.0:8081/one/app.js net::ERR_ABORTED 404 (Not Found)
Main App class:
import * as React from 'react';
import { BrowserRouter, Switch, Route, Link } from 'react-router-dom';
import { One } from './One';
import { Two } from './Two';
import { Three } from './Three';
export class App2 extends React.Component<{}, {}> {
public render() {
return <BrowserRouter>
<ul>
<li>
<Link to='/one'>One</Link>
</li>
<li>
<Link to='/one/two'>Two</Link>
</li>
<li>
<Link to='/one/two/three'>Three</Link>
</li>
</ul>
<Switch>
<Route path='/one/two/three' component={Three} />
<Route path='/one/two' component={Two} />
<Route path='/one' component={One} />
</Switch>
</BrowserRouter>;
}
}
Class named One:
import * as React from 'react';
export class One extends React.Component<{}, {}> {
public render() {
return <div>One</div>;
}
}
Class named Two:
import * as React from 'react';
export class Two extends React.Component<{}, {}> {
public render() {
return <div>Two</div>;
}
}
Class named Three:
import * as React from 'react';
export class Three extends React.Component<{}, {}> {
public render() {
return <div>Three</div>;
}
}
Command to run the app in development mode:
"scripts": {
"develop": "webpack-dev-server --mode development --open --port 8081 --host 0.0.0.0 --config webpack.dev.config.js"
}
The Webpack configuration webpack.dev.config.js:
const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const htmlPlugin = new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
});
module.exports = {
entry: "./src/index.tsx",
output: {
filename: "app.js",
path: path.resolve(__dirname, "dist")
},
// Enable sourcemaps for debuggin webpack's output.
devtool: "source-map",
resolve: {
// Add '.ts', and '.tsx' as resolvable exteensions.
extensions: [".ts", ".tsx", ".js", ".json"]
},
module: {
rules: [
// All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
{ test: /\.tsx?$/, loader: "awesome-typescript-loader" },
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" },
{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "typings-for-css-module-loader", options: { modules: true, namedExport: true, camelCase: true, localIdentName: "[name]_[local]_[hash:base64]" }}
]
},
{
test: /\.scss$/,
exclude: /\.global.scss$/,
use: [
{ loader: "style-loader" },
{ loader: "typings-for-css-modules-loader", options: { modules: true, namedExport: true, camelCase: true, localIdentName: "[local]" }},
{ loader: "postcss-loader", options: { plugins: function () { return [ require("autoprefixer") ]; }}},
{ loader: "sass-loader" }
]
},
{
test: /\.scss$/,
include: /\.global.scss$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{ loader: "postcss-loader", options: { plugins: function () { return [ require("autoprefixer") ]; }}},
{ loader: "sass-loader" }
]
}
]
},
devServer: {
historyApiFallback: true,
disableHostCheck: true
},
plugins: [
new CleanWebpackPlugin({
cleanAfterEveryBuildPatterns: ['dist']
}),
htmlPlugin
]
};
I use the following versions:
Node v13.7.0
"#types/react": "16.9.11",
"#types/react-dom": "16.9.4",
"#types/react-router-dom": "5.1.2",
"react": "16.11.0",
"react-dom": "16.11.0",
"react-router-dom": "5.1.2",
"typescript": "3.7.4",
"webpack": "4.41.2",
"webpack-cli": "3.3.10",
"webpack-dev-server": "3.9.0"
I tried to follow the examples here.
Why does only the 1. route work? Why don't the other routes 2. and 3. work?
Edit 1:
Trying to use exact does not work either. The result is the same as the above mentioned:
import * as React from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import { One } from './One';
import { Two } from './Two';
import { Three } from './Three';
export class App2 extends React.Component<{}, {}> {
public render() {
return <BrowserRouter>
<Switch>
<Route exact path='/one' component={One} />
<Route exact path='/one/two' component={Two} />
<Route exact path='/one/two/three' component={Three} />
</Switch>
</BrowserRouter>;
}
}
Edit 2:
Trying to change the order does not work either. The result is the same as the above mentioned:
import * as React from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import { One } from './One';
import { Two } from './Two';
import { Three } from './Three';
export class App2 extends React.Component<{}, {}> {
public render() {
return <BrowserRouter>
<Switch>
<Route path='/one/two/three' component={Three} />
<Route path='/one/two' component={Two} />
<Route path='/one' component={One} />
</Switch>
</BrowserRouter>;
}
}
Simply: the most specific route goes first. Just reverse your order.
As with most routers each one is checked in sequential order for a match.
Edit 1: evidence https://reacttraining.com/react-router/web/guides/primary-components
Edit 2: Your 404 error indicates to me that the issue is not the router but the server. Did you build the server or is webpack-dev-server a premade server for serving while you develop? I think you'll find that if you go to /one and click a to /one/two it will actually work.
Edit 3: Your webpack Dev server config needs something. I don't have experience with this, but here's a doc webpack.js.org/configuration/output/#outputpublicpath that I think should help.
As suggested in the comments: The final solution is adding publicPath: '/' to output in the Webpack config.
Try to use exact in your <Route/>
Because your paths always start with /one, react router only matches that part, if you want go deeper, you have to tell him exact(ly) what you want.
<Route exact path='/one' component={One} />
<Route exact path='/one/two' component={Two} />
<Route exact path='/one/two/three' component={Three} />
Here's the link to the docs

Webpack React error: You should not use <Switch> outside a <Router>

so i'm trying to setup server side rendering with my React app and I have solved every problem so far but I have run into this one which I cannot solve after a few days of trying.
I'm using the latest of everything included and I run into this error: Error: Invariant failed: You should not use <Switch> outside a <Router>
Below is the react app index
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
const SSR = (
<BrowserRouter>
<App/>
</BrowserRouter>
);
if(typeof document === "undefined") {
module.exports = SSR;
} else {
ReactDOM.hydrate(SSR, document.getElementById("app"));
}
And the component
import React from 'react';
import { Route, Switch } from 'react-router-dom'
import Home from './components/index'
const NavRoute = ({exact, path, component: Component}) => (
<Route exact={exact} path={path} render={(props) => (
<React.Fragment>
<Navbar/>
<Component {...props}/>
</React.Fragment>
)}/>
)
export default class App extends React.Component {
render() {
return (
<Switch>
<NavRoute exact={true} path="/" component={Home}/>
</Switch>
);
}
}
And my webpack config
const path = require('path');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
module.exports = [
{
entry: {
client: './server/index.js',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: "[name].js",
publicPath: '/',
},
target: 'node',
externals: [nodeExternals()],
module: {
rules: [
{ test: /\.jsx?/, loader: "babel-loader"}
]
},
},
{
entry: {
bundle: './src/App.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: "[name].js",
publicPath: '/',
libraryTarget: "umd",
globalObject: "this",
},
module: {
rules: [
{ test: /\.jsx?/, loader: "babel-loader"}
]
},
plugins: [
new webpack.DefinePlugin({
'process.env.BROWSER': JSON.stringify(true),
}),
]
}
]
any help is appreciated let me know if I missed any info out, thank you.

Navigate to a specific page by url in React

How do I navigate to a specific page with url in React?
I realized I've used CRA in the past and haven't really tackled this specifically.
Currently I'm rendering ReactDOM with BrowserRouter and Switch with exact path in Routes
// index.jsx
/* eslint-disable import/extensions */
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './app/App.jsx';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root'),
);
// App.jsx
import React from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import Header from '../components/Header';
import HomePage from '../pages/Home';
import PlansPage from '../pages/Plans';
import NotFoundPage from '../pages/NotFound';
const App = () => (
<BrowserRouter>
<Header />
<Switch>
<Route exact path="/" component={HomePage} />
<Route exact path="/plans" component={PlansPage} />
<Route component={NotFoundPage} />
</Switch>
</BrowserRouter>
);
export default App;
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const webpack = require('webpack');
module.exports = {
devtool: false,
module: {
rules: [
{
test: /\.m?(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.scss$/,
use: [{
loader: 'style-loader',
options: {
sourceMap: true,
},
}, {
loader: 'css-loader',
options: {
sourceMap: true,
},
}, {
loader: 'sass-loader',
options: {
sourceMap: true,
},
}],
},
],
},
entry: './src/index.jsx',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'index_bundle.js',
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: './index.html',
}),
new webpack.SourceMapDevToolPlugin({}),
],
};
Navigating to http://localhost:8080/plans leads to a page with Cannot GET /plans. However, clicking on a Link element navigates to that plans page without an issue.
Yeah since you're using webpack Dev Server all you have to do is add historyApiFallback=true and it'll fix you issue. You're essentially telling all routes to fall back to your index.html file. Hope that helped.

react-router v4 browserRouter is not working

i don't know what is diffrence in my code.
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const AsyncChunkNames = require('webpack-async-chunk-names-plugin');
const lunaRocketModulesPath = path.resolve(__dirname, 'luna-rocket');
module.exports = {
entry: [
'#babel/polyfill',
path.join(__dirname,'src/app','app.js')
],
output: {
path: path.join(__dirname,'build'),
filename: 'index.bundle.js',
chunkFilename: '[name].bundle.js',
publicPath: '/', // 헐랭이.. 이 게 뭐길래...
},
mode: process.env.NODE_ENV || 'development',
resolve: {
alias: {
'luna-rocket': lunaRocketModulesPath
},
extensions: [
'.js',
],
},
devServer: {
contentBase: path.join(__dirname,'src'),
disableHostCheck: true,
historyApiFallback: true
},
module: {
rules: [
{
// this is so that we can compile any React,
// ES6 and above into normal ES5 syntax
test: /\.(js)$/,
// we do not want anything from node_modules to be compiled
exclude: /node_modules/,
use: {
loader: 'babel-loader',
}
},
{
test: /\.(css|scss)$/,
use: [
"style-loader", // creates style nodes from JS strings
"css-loader", // translates CSS into CommonJS
"sass-loader" // compiles Sass to CSS, using Node Sass by default
]
},
{
test: /\.(jpg|jpeg|png|gif|mp3|svg)$/,
loaders: ['file-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname,'src','index.html'),
inject: 'body',
}),
// new AsyncChunkNames()
],
optimization: {
splitChunks:{
cacheGroups: {
default: false,
vendors: false,
vendor: {
name: 'vender',
chunks: "all",
test: "/node_module/",
priority: 20
},
common: {
name: 'common',
minChunks: 2,
chunks: "all",
priority: 10,
reuseExistingChunk: true,
enforce: true
}
}
}
}
};
app.js
import React, { Suspense, lazy } from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route, Switch, HashRouter, withRouter, useRouterHistory , Redirect} from 'react-router-dom'
import Home from './Home';
import RocketComponent from './RocketComponent';
const Loading = () => <div>loading...</div>
ReactDOM.render(
<Router>
<div className="app">
<div className="container">
<Suspense fallback={<Loading />}>
<Route exact path="/" component={Home} />
<Route path="/rocket" component={RocketComponent} />
</Suspense>
</div>
</div>
</Router>,
document.getElementById('app')
);
RocketComponent.js
import HeaderNew from "./HeaderNew";
import React, {lazy, Suspense} from 'react';
import RocketMenuNew from "./RocketMenuNew";
import {Route, Switch} from "react-router-dom";
function scrollToTop() {
document.body.scrollTop = 0
}
const menuData = [
{
title: "LUXAccordion",
path: "/rocket/LUXAccordion",
component: "./Documents/LUXAccordion/AccordionDocument"
},
{
title: "LUXActionBar",
path: "/rocket/LUXActionBar",
component: "./Documents/LUXActionBar/ActionBarDocument"
},
{
title: "LUXBadge",
path: "/rocket/LUXBadge",
component: "./Documents/LUXBadge/BadgeDocument"
},
{
title: "LUXButton",
path: "/rocket/LUXButton",
component: "./Documents/LUXButton/ButtonDocument"
}
]
function DynamicLoader(props) {
// console.log("title", `./Documents/${title.title}/${title.title.substring(3)}Document`)
// const LazyComponent = React.lazy(() => import(`./Documents/${title.title}/${title.title.substring(3)}Document`));
const LazyComponent = lazy(() => import(`${props.component}`));
console.log("LazyComponent", LazyComponent)
return (
<LazyComponent />
);
}
class RocketComponent extends React.Component {
render() {
console.log("this.props.match.path", this.props.match.path)
return (
<div className="documents-new">
<HeaderNew />
<RocketMenuNew />
<Switch>
{menuData.map((props, i) => {
return <Route path={props.path} render={() => <DynamicLoader component={props.component}/>} key={i}/>
})}
</Switch>
</div>
);
}
}
export default RocketComponent
this code is working.
but RocketComponent.js moves to the route directory. is not working.
i don't know why??
RocketComponent.js --> path: app/router/RocketComponent.js
import HeaderNew from "./../HeaderNew";
import React, {lazy, Suspense} from 'react';
import RocketMenuNew from "./../RocketMenuNew";
import {Route, Switch} from "react-router-dom";
function scrollToTop() {
document.body.scrollTop = 0
}
const menuData = [
{
title: "LUXAccordion",
path: "/rocket/LUXAccordion",
component: "./../Documents/LUXAccordion/AccordionDocument"
},
{
title: "LUXActionBar",
path: "/rocket/LUXActionBar",
component: "./../Documents/LUXActionBar/ActionBarDocument"
},
{
title: "LUXBadge",
path: "/rocket/LUXBadge",
component: "./../Documents/LUXBadge/BadgeDocument"
},
{
title: "LUXButton",
path: "/rocket/LUXButton",
component: "./../Documents/LUXButton/ButtonDocument"
}
]
function DynamicLoader(props) {
const LazyComponent = lazy(() => import(`${props.component}`));
return (
<LazyComponent />
);
}
class RocketComponent extends React.Component {
render() {
return (
<div className="documents-new">
<HeaderNew />
<RocketMenuNew />
<Switch>
{menuData.map((props, i) => {
return <Route path={props.path} render={() => <DynamicLoader component={props.component}/>} key={i}/>
})}
</Switch>
</div>
);
}
}
export default RocketComponent
i modify the component path and app.js modify RocketComponent path right.
but is not working
the error is
why is not working, the path is right, please help me .
my webpack is 4, babel 7

Module not found when import .jsx file

I can't find out the solution. I'm using Reactstrap (CSS framework), React, Express, and Webpack.
I was success to import App.jsx file on index.jsx. Then, I tried to import NavbarTemplate.jsx file on App.jsx by using the same way. But, it displayed error like this :
ERROR in ./client/src/components/App.jsx
Module not found: Error: Can't resolve 'NavbarTemplate.jsx' in '/Users/oprent1/v2/oprent-react/client/src/components'
# ./client/src/components/App.jsx 11:22-51
# ./client/src/index.jsx
What is wrong with my configuration ? I have provided several files that related to this below :
webpack.config.js
const path = require('path');
module.exports = {
entry: path.join(__dirname, '/client/src/index.jsx'),
output: {
path: path.join(__dirname, '/client/dist/js'),
filename: 'app.js',
},
module: {
loaders: [
{
test: /\.jsx?$/,
include: path.join(__dirname, '/client/src'),
// loader: 'babel',
loader: 'babel-loader',
query: {
presets: ["react", "es2015"],
plugins: ["transform-class-properties"]
}
},
{
test: /\.css$/,
loader: 'style-loader!css-loader'
}
],
},
watch: true
};
index.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import Bootstrap from 'bootstrap/dist/css/bootstrap.css';
import App from './components/App.jsx'; //SUCCESS when imported
ReactDOM.render(
<App />,
document.getElementById('react-app')
);
App.jsx
import React from 'react';
import NavbarTemplate from 'NavbarTemplate.jsx'; //ERROR when imported
const App = (props) => {
return (
<div>
<NavbarTemplate />
</div>
);
};
export default App;
NavbarTemplate.jsx
import React, { PropTypes } from 'react';
import { Collapse, Navbar, NavbarToggler, NavbarBrand, Nav, NavItem, NavLink } from 'reactstrap';
class NavbarTemplate extends React.Component {
constructor(props) {
super(props);
this.toggleNavbar = this.toggleNavbar.bind(this);
this.state = {
collapsed: true
};
}
toggleNavbar() {
this.setState({
collapsed: !this.state.collapsed
});
}
render() {
return (
<div>
<Navbar color="faded" light>
<NavbarToggler onClick={this.toggleNavbar} />
<Collapse className="navbar-toggleable-md" isOpen={!this.state.collapsed}>
<NavbarBrand href="/">reactstrap</NavbarBrand>
<Nav navbar>
<NavItem>
<NavLink href="/components/">Components</NavLink>
</NavItem>
<NavItem>
<NavLink href="https://github.com/reactstrap/reactstrap">Github</NavLink>
</NavItem>
</Nav>
</Collapse>
</Navbar>
</div>
);
}
}
export default NavbarTemplate;
Folder Structure
according with webpack can't find module if file named jsx if you don't want to add .jsx on your import you could add resolve: { extensions: ['.js', '.jsx'] } to your webpack.config.
// ...
module: {
loaders: [
{
test: /\.jsx?$/,
include: path.join(__dirname, '/client/src'),
// loader: 'babel',
loader: 'babel-loader',
query: {
presets: ["react", "es2015"],
plugins: ["transform-class-properties"]
}
},
{
test: /\.css$/,
loader: 'style-loader!css-loader'
}
]
},
resolve: {
extensions: ['.js', '.jsx']
}
// ...
To import files in the same folder you have to use
./nameOfTheFile
Instead of
nameOfTheFile
So your important statement would be
import NavbarTemplate from './NavbarTemplate.jsx';
if your App.jsx and NavbarTemplate.jsx are in the same root directory then just try
import NavbarTemplate from './NavbarTemplate';
it should work
so basically . represents the parent folder when you try to do something in cmd also.so doing ./NavbarTemplate will resolve your issue as you are importing module from the same folder
If you are using a JSX file extension, you need to import like below code,
import NavbarTemplate from './NavbarTemplate.jsx';
If you are using a JS file extension, you need to import like below code,
import NavbarTemplate from './NavbarTemplate';

Resources