React Route cannot render - reactjs

I ran into the error:"Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.".I don't know how to fix it! It'd be kind of you guys to help me! Thank you so much!
This is my Layout.jsx:
import React from 'react'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import Header from "./Header"
import Routes from '../routes/Routes'
const Layout = () => {
return (
<Router>
<Route render={props => (
<div>
<Header {...props}/>
<div className="container">
<div className="main">
<Routes/>
</div>
</div>
</div>
)}/>
</Router>
)
}
export default Layout
This is my Routes.jsx:
import React from 'react'
import {BrowserRouter as Router, Route, Switch} from "react-router-dom"
import Home from '../pages/Home';
import Catalog from '../pages/Catalog';
import Cart from "../pages/Cart";
import Product from '../pages/Product';
const Routes = () => {
return (
<Router>
<Switch>
<Route path='/' exact component={Home}/>
<Route path='/catalog:slug' component={Product}/>
<Route path='/catalog' component={Catalog}/>
<Route path='/cart' exact component={Cart}/>
</Switch>
</Router>
)
}
export default Routes

Related

Changed syntax in react-route-dom from 'Switch' to 'Routes' but still no display in the browser

I'm creating a Google Clone. This is my current code for that. I read that I needed to changed the syntax from 'Switch' to 'Routes', given the update for react-router. I did just that and my "This is the search page" is not displaying inside of the browser.
import React from "react";
import './App.css';
import Home from './pages/Home';
import { BrowserRouter as Router, Routes, Route } from "react-router-dom"
function App() {
return (
// BEM
<div className="app">
<Router>
<Routes>
<Route path="/search">
<h1>This is the search page</h1>
</Route>
<Route path="/">
<Home />
</Route>
</Routes>
</Router>
</div>
);
}
export default App;
you need to create each component speratly some things like this:
import React from 'react;
function Home(){
return(
<div>
<h1>Home</h1>
</div>
);
}
export default Home;
import React from 'react;
function Search(){
return(
<div>
<h1>Search</h1>
</div>
);
}
export default Search;
change index.js to :
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById("root"));
change App.js to
import React, {useEffect} from 'react';
import ReactDOM from "react-dom";
import { BrowserRouter ,Routes,Route} from 'react-router-dom';
import Search from '.........'
import Home from '.......'
function App(){
return(
<BrowserRouter>
<Routes>
<Route exact path="/" element={<Home/>} />
<Route path="/search" element={<Search/>} />
<Routes>
</BrowserRouter>
);
}
export default App;
if(document.getElementById('app')){
ReactDOM.render(<App/>,document.getElementById('app'));
}
In react-router-dom#6 the Routecomponent API changed significantly. Thechildrenprop is only used for rendering nestedRoutecomponents. All routed content is now rendered on a singleelementprop taking aReactNode`, a.k.a. JSX.
Move the content from being wrapped into the element prop.
function App() {
return (
// BEM
<div className="app">
<Router>
<Routes>
<Route path="/search" element={<h1>This is the search page</h1>} />
<Route path="/" element={<Home />} />
</Routes>
</Router>
</div>
);
}
Route component expects 2 parameters path, and element.
Refer to the official doc here
function App() {
return(
<BrowserRouter>
<Routes>
<Route path="/" element={<Home/>} />
<Route path="/search" element={<Search/>} />
<Routes>
</BrowserRouter>
);
}

A <Route> is only ever to be used as the child of <Routes> element, never rendered directly

I was trying to display my layout.jsx on the browser but keep getting "A <Route> is only ever to be used as the child of Routes element, never rendered directly;" error I tried wrapping it in Routes but keep getting the error.
import React from 'react'
import Sidebar from '../sidebar/Sidebar';
import Routes from '../Routes';
import {BrowserRouter, Route} from 'react-router-dom';
const Layout = () => {
return (
<BrowserRouter>
<Route render={(props) =>(
<div className='layout'>
<Sidebar {...props} />
<div className="layout__content">
<div className="layout__content-main">
<Routes />
</div>
</div>
</div>
)
} />
</BrowserRouter>
)
}
export default Layout
import React from 'react';
import {Route, Routes} from 'react-router-dom';
import Dashboard from '../pages/Dashboard';
import Customers from '../pages/Customers';
const RRoutes = () => {
return (
<Routes>
<Route path='/' component={Dashboard} />
<Route path='/customers' component={Customers}/>
</Routes>
)
}
export default RRoutes
import React from 'react'
const Sidebar = () => {
return (
<div>
Hello Sidebar
</div>
)
}
export default Sidebar
Since you are using react-router-dom#6 the Route component API changed quite a bit. There are no longer any component or render and children function props, they were replaced by a single element prop taking a ReactNode, a.k.a. JSX. Additionally, all Route components must be rendered by a Routes component, the spiritual successor to the v5 Switch component that handles route matching and rendering.
import React from 'react'
import {BrowserRouter, Route} from 'react-router-dom';
import Sidebar from '../sidebar/Sidebar';
import MyRoutes from '../Routes';
const Layout = () => {
return (
<BrowserRouter>
<div className='layout'>
<Sidebar />
<div className="layout__content">
<div className="layout__content-main">
<MyRoutes />
</div>
</div>
</div>
</BrowserRouter>
);
}
...
import React from 'react';
import { Route, Routes } from 'react-router-dom';
import Dashboard from '../pages/Dashboard';
import Customers from '../pages/Customers';
const MyRoutes = () => {
return (
<Routes>
<Route path='/' element={<Dashboard />} />
<Route path='/customers' element={<Customers />}/>
</Routes>
);
}
export default MyRoutes;

How would I go about creating a react router in Typescript?

In a normal react project my router would look like this
I would have my app wrapped in a Component , and then I would have this
<Switch>
<Route path="/login" render={(props) => <LoginPage login={this.login} authed={this.state.isAuthenticated} {...props} />} />
<Route path="/" render={(props) => this.props.history.push("/login")} />
</Switch>
But I dont know how to simulate something similar in typescript . I currently have this
const App: React.FunctionComponent = () => {
return (
<Router>
<div className="main-content">
<div>
<Switch>
<Route exactly component={Main} exact pattern="/" />
<Route exactly component={Count} exact pattern="/count" />
</Switch>
</div>
</div>
</Router>
);
};
But it always redirects to main component. How could I do that an undefined route like /randomroute , would redirect to "/" , and how would I make the alternative route /count work?
EDIT: I have progressed a bit
import React from "react";
import { BrowserRouter as Router, Route, Switch, RouteComponentProps, RouteProps } from "react-router-dom";
import Main from "./components/Main";
import Count from "./components/Count"
import "./App.css";
interface ChildComponentProps extends RouteProps {
/* other props for ChildComponent */
}
const App: React.FunctionComponent<ChildComponentProps> = (props) => {
return (
<Router>
<div className="main-content">
<div>
<Switch>
<Route exactly component={Main} exact path="/" />
<Route exactly component={Count} exact path="/count" />
<Route pattern ="/" render={() => props.history.push("/") } />
</Switch>
</div>
</div>
</Router>
);
};
export default App;
Problem now is that, history is inside the RouteComponentProps interface, while RouteProps interface contains render, and I cant use them at the same time, so im a bit lost
EDIT2: Trying this
interface RenderProps extends RouteProps {
/* other props for ChildComponent */
}
interface HistoryProps extends RouteComponentProps {
}
const App: React.FunctionComponent<HistoryProps & RenderProps>
Receiving in render
The expected type comes from property 'render' which is declared here
on type 'IntrinsicAttributes &
IntrinsicClassAttributes<Route> & Readonly &
Readonly<...>'
When supposedly that interface is imported
Edit4:
I did this
import React from "react";
import { BrowserRouter as Router, Route, Switch, RouteComponentProps, RouteProps, withRouter } from "react-router-dom";
import Main from "./components/Main";
import Count from "./components/Count"
import "./App.css";
interface RenderProps extends RouteProps {
/* other props for ChildComponent */
}
interface HistoryProps extends RouteComponentProps {
}
const App: React.FunctionComponent<RenderProps & HistoryProps> = (props) => {
return (
<div className="main-content">
<div>
<Switch>
<Route exactly component={Main} exact path="/" />
<Route exactly component={Count} exact path="/count" />
<Route path ="/" {...props.history.push("/")} />
</Switch>
</div>
</div>
);
};
export default withRouter(App);
And wrapper the app component in index.tsx file into (browserouter)
Now im getting a
Error: Maximum update depth exceeded. This can happen when a component
repeatedly calls setState inside componentWillUpdate or
componentDidUpdate. React limits the number of nested updates to
prevent infinite loops
Because of the props.history.push
I ended up doing this, but im waiting for better answers
import React from "react";
import { Route, Switch, RouteComponentProps, withRouter} from "react-router-dom";
import Main from "./components/Main";
import Count from "./components/Count";
import Redirector from "./components/Redirect"
import "./App.css";
interface HistoryProps extends RouteComponentProps {
}
const App: React.FunctionComponent<HistoryProps> = (props) => {
return (
<div className="main-content">
<div>
<Switch>
<Route exactly component={Main} exact path="/" />
<Route exactly component={Count} exact path="/count" />
<Route path ="/" exactly component={Redirector}/>
</Switch>
</div>
</div>
);
};
export default withRouter(App);
Redirect.tsx
import * as React from "react";
import { Redirect } from "react-router-dom";
const Redirector: React.FunctionComponent = () => {
return <Redirect to='/'/>;
};
export default Redirector
EDIT2: Probably a better approach
import React from "react";
import { Route, Switch, withRouter, Redirect} from "react-router-dom";
import Main from "./components/Main";
import Count from "./components/Count";
import "./App.css";
const App: React.FunctionComponent = () => {
const renderFor404Routes = () => (<Redirect to='/'/>);
return (
<div className="main-content">
<div>
<Switch>
<Route exactly component={Main} exact path="/" />
<Route exactly component={Count} exact path="/count" />
<Route path ="/" exactly component={renderFor404Routes}/>
</Switch>
</div>
</div>
);
};
export default withRouter(App);

ReactJS: Check the render method of `MainRouter`. Error

I'm trying to export two named modules from one component file and somehow keep getting the "Check the render method..." error.
Here's a look at my code.
App.jsx
import React from 'react';
import { MainRouter } from '../Router';
const App = () => (
<div className="card">
<MainRouter />
</div>
);
export default App;
Router.jsx - which is what's being imported above
import React, { Fragment } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import PrivateRoute from './components/PrivateRoute';
import Header from './components/Header';
import AdminNav from './components/AdminNav';
import Calendar from './pages/Calendar';
import Search from './pages/Search';
import AdminLogin from './pages/AdminLogin';
import Admin from './pages/Admin';
import New from './pages/Admin/New';
import Users from './pages/Admin/Users';
let styles = {};
styles.body__wrapper = {
padding: '2%'
};
export const MainRouter = () => (
<Router>
<Fragment>
<div className="nav__wrapper">
<Header />
</div>
<div style={styles.body__wrapper}>
<Switch>
<Route exact path="/" component={Calendar} />
<Route path="/search/:name" component={Search} />
<Route path="/admin/signin" component={AdminLogin} />
<PrivateRoute path="/admin" component={Admin} />
</Switch>sasd
</div>
</Fragment>
</Router>
);
export const AdminRouter = (props) => (
<div className="container">
<Router>
<Fragment>
<AdminNav {...props}/>
<div className="my-3">
<Switch>
<Route path="/users" component={Users} />
<Route path="/new" component={New} />
</Switch>
</div>
</Fragment>
</Router>
</div>
);
I've tried doing export { MainRouter, AdminRouter } but doesn't seem to work as well.
Complete error message:
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `MainRouter`.
I actually figured it out.
I was using several index.js on every route component and incorrectly configured the exports on almost all of them, causing the whole app to crash.

named path not working in react-router-dom react js

I am using react-router-dom for routing purposes. This is my code:
//Libraries
import React from 'react';
import { Tabs, Tab } from 'react-tabify';
import { connect } from 'react-redux';
import {
BrowserRouter as Router,
Route,
withRouter
} from 'react-router-dom';
//Components
import HomePage from './containers/HomePage';
import PersonsPage from './containers/PersonsPage';
const App = () => (
<Router>
<div style={{height: '100%', width: '100%'}}>
<Route exact path="/" component={HomePage}/>
<Route exact path="/:id" component={PersonsPage}/>
// here i want to use like this --> <Route exact path="/personPage/:id" component={PersonsPage}/>
</div>
</Router>
)
export default withRouter(connect()(App));
Route exact path="/:id" component={PersonsPage}/> this works , but this Route exact path="/personPage/:id" component={PersonsPage}/> this didn't works for me . Can someone clarify/help me from this pls
I think you should simply wrap your routers in Switch component. But remember to put <Route exact path="/:id" component={PersonsPage}/> as last entry.
Here you have an example in one file:
import React, { Component } from 'react';
import { render } from 'react-dom';
import {
BrowserRouter as Router,
Route,
Switch,
Link,
withRouter
} from 'react-router-dom';
const HomePage = () => (
<div>
<h1>HomePage</h1>
<ul>
<li><Link to="/user/Tom">Tom</Link></li>
<li><Link to="/user/John">John</Link></li>
<li><Link to="/user/Andy">Andy</Link></li>
</ul>
</div>
);
const PersonsPage = (props) => (
<div>
<h1>Profile: {props.match.params.name}</h1>
</div>
);
class App extends Component {
render() {
return (
<Switch>
<Route exact path="/" component={HomePage}/>
<Route exact path="/user/:name" component={PersonsPage}/>
</Switch>
);
}
}
const AppWithRouter = withRouter(App);
render(
<Router>
<AppWithRouter />
</Router>
, document.getElementById('root')
);
Here you have link to working version https://stackblitz.com/edit/react-qqpraz

Resources