I'm following this guide Meteor React Routing but unfortunately, my app now renders nothing (after adding routing, the app was working fine before-hand), and I can't see anything wrong
App.jsx
import React, { Component } from 'react';
import Navigation from './components/Navigation';
import LoginForm from './components/LoginForm';
export default class App extends Component {
render() {
return (
<div>
<Navigation />
<p>
<h1>Something here</h1>
</p>
</div>
);
}
}
main.js
import React from 'react';
import { Meteor } from 'meteor/meteor';
import { render } from 'react-dom';
import { renderRoutes } from './Routes.jsx';
Meteor.startup(() => {
render(renderRoutes(), document.getElementById('app'));
});
Routes.jsx
import React from 'react';
import { render } from 'react-dom';
import { Router, Route } from 'react-router';
import createBrowserHistory from 'history/createBrowserHistory';
import App from '../imports/ui/App.jsx';
import LoginForm from '../imports/ui/components/LoginForm.jsx';
const browserHistory = createBrowserHistory();
export const renderRoutes = () => (
<Router history={browserHistory}>
<Route exact path="/" component={App} />
<Route path="/login" component={LoginForm} />
</Router>
);
..and the html
<head>
<title>Some title</title>
</head>
<body>
<div id="app"></div>
</body>
I've verified that all imports resolve. And when running meteor, there are no errors. Nor are there any errors in the console of the browser, yet there is just a blank page. Have I missed something?
You are not returning your routes.
It should be like below,
export const renderRoutes = () => (
<Router history={browserHistory}>
<Route exact path="/" component={App} />
<Route path="/login" component={LoginForm} />
</Router>
);
// or
export const renderRoutes = () => {
return (
<Router history={browserHistory}>
<Route exact path="/" component={App} />
<Route path="/login" component={LoginForm} />
</Router>
);
};
Unfortunately there was an error that wasn't being thrown in Meteor. There was an issue with my Router definition, what it should actually be is:
export const renderRoutes = () => (
<Router history={browserHistory}>
<div>
<Route exact path="/" component={App} />
<Route path="/login" component={LoginForm} />
</div>
</Router>
);
Notice the inclusion of div - as it would appear that Router can only have one child element.
Related
I have problem with router-dom. I am working according to youtube tutorial, I cannot resolve below error:
[landingPageLayout] is not a component. All component children of must be a or <React.Fragment>. I would be greateful for some guidance.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
App.js
import './App.css';
import { Routes, Route } from 'react-router-dom';
import landingPageLayout from './components/layouts/landingPageLayout';
import homePage from './components/pages/homePage';
const App = () => {
return (
<Routes>
<landingPageLayout>
<Route path="/">
<homePage/>
</Route>
</landingPageLayout>
</Routes>
);
}
landingPageLayout.js
import React from 'react';
import Header from '../navigation/header';
const landingPageLayout = ({...otherProps}) => {
return (
<div>
<Header/>
</div>
)
}
export default landingPageLayout;
As Nicholas said in comments, your react components should always be capitalized.
Other than that, Routes component only accepts or <React.Fragment> as children so you can't add your layout like that. What you can do is something like this:
const App = () => {
return (
<Routes>
<Route
path='/*'
element={
<LandingPageLayout>
<HomePage />
</LandingPageLayout>
}
/>
</Routes>
);
}
If you have several routes that need this layout, you should replace HomePage with another component that has all the routes. For example we can call it PrivateRoutes. Then in code above you replace <HomePage /> with <PrivateRoutes /> and then your PrivateRoutes component should look like this:
const PrivateRoutes = () => {
return (
<Routes>
<Route path="home" element={<HomePage />} />
<Route path="page1" element={<Page1 /> />
//rest of routes
</Routes>
);
}
Im trying to figure out how to get my navigation bar setup as most of the UI is coming together. I have setup my index.js and also a Route.js and then linked them with my different components like so:
Index.js
import React from "react";
import ReactDOM from "react-dom";
import { Auth0Provider } from "./react-auth0-spa.js";
import { useAuth0 } from "./react-auth0-spa";
import Routes from "./Routes"
import config from "./utils/auth_config.json";
import { BrowserRouter } from "react-router-dom";
// A function that routes the user to the right place
// after login
const onRedirectCallback = appState => {
history.push(
appState && appState.targetUrl
? appState.targetUrl
: window.location.pathname
);
};
ReactDOM.render(
<Auth0Provider
domain={config.domain}
client_id={config.clientId}
redirect_uri={window.location.origin}
onRedirectCallback={onRedirectCallback}
>
<BrowserRouter>
<Routes />
</BrowserRouter>
</Auth0Provider>,
document.getElementById("root")
);
Routes.js
import React, { Component } from "react";
import { Router, Route, Switch, BrowserRouter } from "react-router-dom";
import {Link } from "react-router-dom";
import Profile from "./components/user/Profile";
import PrivateRoute from "./components/user/PrivateRoute";
import history from "./utils/history.js";
import HomePage from "./modules/HomePage.js";
import ProductPage from "./modules/ProductPage";
class Routes extends Component {
render() {
return (
<Router history={history}>
<Switch>
<Route path="/" component={HomePage} />
<Route path="/ProductPage" component={ProductPage} />
<PrivateRoute path="/profile" component={Profile} />
</Switch>
</Router>
)
}
}
export default Routes;
but when i reload my site it just continues to say localhost:8080/ProductPage like its suppose to be the default, then when i manually enter localhost:8080/ and click on a button after linking it with
<Link to="ProductPage">
it will show on the tab localhost:8080/ProductPage but wont actually redirect me to the other component, i am just wondering what i am doing wrong?
Issue
You have your "home" route listed first in the Switch.
Switch
Renders the first child <Route> or <Redirect> that matches the location.
"/" is less specific and matches basically all routes, so even though the URL is "/ProductPage", "/" still matches it and HomePage is rendered.
Solution
Either move it after the other more specific routes or use the exact prop on it.
<Router history={history}>
<Switch>
<Route path="/ProductPage" component={ProductPage} />
<PrivateRoute path="/profile" component={Profile} />
<Route path="/" component={HomePage} />
</Switch>
</Router>
or
<Router history={history}>
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/ProductPage" component={ProductPage} />
<PrivateRoute path="/profile" component={Profile} />
</Switch>
</Router>
I have a react app. It is working fine. It uses redux,react-router 3. The routes work fine, but when I press the back button, they route gets duplicated. For example from localhost:3000/admin/main which I am currently, when I go back, it goes to localhost:3000/admin/admin/main, which return not found.
Here is my routes code:
export default (
<Route path="/" component={App}>
<Route path="home" component={requireNoAuthentication(HomeContainer)} />
<Route path="login" component={requireNoAuthentication(LoginView)} />
<Route exact path="admin/user" component={requireAuthentication(UserView)} />
<Route exact path="admin/main" component={requireAuthentication(UsersListView)} />
<Route path="secure" component={requireAuthentication(CustomerView)} />
<Route exact path="*" component={DetermineAuth(NotFound)} />
</Route>
);
I also get a console error: Adjacent JSX elements must be wrapped in an enclosing tag. If anyone can help it would be great thanks!!
Your HOC wrappers (requireNoAuthentication and requireAuthentication) and using exact (I think this might a react-router v4 only feature?) might be messing with your route history. Try restructuring your routes so that all of them fall under App -- some of the routes fall under RequireAuth, while the rest are public.
As a side note: you can avoid using React.cloneElement with passed down class methods and state by using Redux instead.
routes/index.js
import React from "react";
import { browserHistory, IndexRoute, Router, Route } from "react-router";
import App from "../components/App";
import Home from "../components/Home";
import Info from "../components/Info";
import ShowPlayerRoster from "../components/ShowPlayerRoster";
import ShowPlayerStats from "../components/ShowPlayerStats";
import Schedule from "../components/Schedule";
import Sponsors from "../components/Sponsors";
import RequireAuth from "../components/RequireAuth";
export default () => (
<Router history={browserHistory}>
<Route path="/" component={App}>
<Route component={RequireAuth}>
<IndexRoute component={Home} />
<Route path="roster" component={ShowPlayerRoster} />
<Route path="roster/:id" component={ShowPlayerStats} />
<Route path="schedule" component={Schedule} />
</Route>
<Route path="info" component={Info} />
<Route path="sponsors" component={Sponsors} />
</Route>
</Router>
);
index.js
import React from "react";
import { render } from "react-dom";
import App from "../routes";
import "uikit/dist/css/uikit.min.css";
render(<App />, document.getElementById("root"));
components/App.js
import React, { Component, Fragment } from "react";
import { browserHistory } from "react-router";
import Header from "./Header";
export default class App extends Component {
state = {
isAuthenticated: false
};
isAuthed = () => this.setState({ isAuthenticated: true });
unAuth = () =>
this.setState({ isAuthenticated: false }, () => browserHistory.push("/"));
render = () => (
<Fragment>
<Header
isAuthenticated={this.state.isAuthenticated}
unAuth={this.unAuth}
/>
{React.cloneElement(this.props.children, {
isAuthenticated: this.state.isAuthenticated,
isAuthed: this.isAuthed
})}
</Fragment>
);
}
components/RequireAuth.js
import React, { Fragment } from "react";
import Login from "./Login";
export default ({ children, isAuthenticated, isAuthed }) =>
!isAuthenticated ? (
<Login isAuthed={isAuthed} />
) : (
<Fragment>{children}</Fragment>
);
Out of the blue this warning started appearing in console and I don't know how to get rid of it.
This is the main part of my ./app/src/routes.js file:
import React from 'react';
import { Provider } from 'react-redux';
import { Router, Route, IndexRoute } from 'react-router';
import store, { history } from './store';
import AppContainer from './containers/AppContainer'; // eslint-disable-line
import * as Pages from './pages';
import AppHolder from './containers/AppHolderContainer/index';
import { isAuthorized } from './network';
const RouterApp = () => (
<Provider store={store}>
<Router history={history}>
<Route path="/" component={AppContainer}>
<Route path="login" component={Pages.LoginPage} />
<IndexRoute component={Pages.LoginPage} />
</Route>
<Route path="app" component={AppHolder} >
<IndexRoute component={Pages.EmployeePage} />
<Route path="reservationmap" component={Pages.EmployeePage} />
<Route path="manager" component={Pages.ManagerPage} />
<Route path="permissions" component={Pages.AdminPage} />
</Route>
<Route path="*" component={Pages.LoginPage} />
</Router>
</Provider>
);
export default RouterApp;
I don't understand why the following code produces the error in the title. I checked similar questions, but I did not find them helpful.
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import { createHashHistory } from 'history';
import Menu from './pages/Menu';
import BookShelf from './pages/BookShelf';
import BorrowBook from './pages/BorrowBook';
const App = React.createClass({
contextTypes: {
router: React.PropTypes.object.isRequired
},
render() {
return (
<Menu />
);
}
});
ReactDOM.render((
<Router history={browserHistory} onUpdate={() => window.scrollTo(0, 0)}>
<Route path="/" component={App}/>
<Route path="/menu" component={Menu} />
<Route path="/bookshelf" component={BookShelf} />
<Route path="/borrowbook/:bookId" component={BorrowBook} />
</Router>,
document.getElementById('app')
));
ReactDOM.render(( // extra parenthesis here
<Router history={browserHistory} onUpdate={() => window.scrollTo(0, 0)}>
<Route path="/" component={App}/>
<Route path="/menu" component={Menu} />
<Route path="/bookshelf" component={BookShelf} />
<Route path="/borrowbook/:bookId" component={BorrowBook} />
</Router>,
document.getElementById('app')
)); // extra parenthesis here
The extra parenthesis are making it so that you are actually passing one argument instead of two.