Everytime I execute history.push("/path") the url changes to the correct path but the 404 PageNotFound component gets renderered.
// indes.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import {App} from './App';
import history from "./customHistory";
import {Router} from "react-router";
ReactDOM.render(
<React.StrictMode>
<Router history={history}>
<App/>
</Router>
</React.StrictMode>,
document.getElementById('root')
);
/// App.tsx
import React, {Component} from "react"
import {Route, Switch} from "react-router-dom";
import {FrontPage} from './components/FrontPage'
import {LoginPage} from "./components/LoginPage";
import {PageNotFound} from "./components/PageNotFound";
import {RequestPasswordResetPage} from "./components/RequestPasswordResetPage";
export class App extends Component {
render() {
return (
<Switch>
<Route path={"/"} component={FrontPage} exact={true}/>
<Route path={"/login"} component={LoginPage} exact={true}/>
<Route path={"/request_password_reset"} component={RequestPasswordResetPage}
exact={true}/>
<Route path={""} component={PageNotFound}/>
</Switch>
)
}
}
My history object is the following
// customHistory.ts
import { createBrowserHistory } from "history";
export default createBrowserHistory({});
And I call the history.push after the user requested a password reset:
// RequestPasswordResetPage.tsx
private handleSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
AccountService.requestPasswordReset(this.state.email)
.then((ans: Response) => {
if (ans.ok) {
console.log("REDIRECT TO HOME");
history.push("/login");
} else {
throw Error(ans.statusText);
}
});
}
Everytime the url changes to localhost:3000/login but the PageNotFound component gets rendered.
Use react-router v5.2.0 and history v4.9.0 to make this work.
https://codesandbox.io/s/quizzical-dan-z3725
OR
Try using BrowserHistory
https://reactrouter.com/web/example/basic
seems there is some issue with customHistory when we use different version
Related
I am relatively new to React and can't for the life of me figure out why this isn't working!
This code is not loading the App component inside router, but it does when returned independently. Example below
import React from "react";
import ReactDOM from "react-dom";
import App from "../components/App";
import { Router, Route } from "react-router-dom";
document.addEventListener("DOMContentLoaded", () => {
ReactDOM.render(
<Router>
<Route path="/">
<App />
</Route>
</Router>,
document.body.appendChild(document.createElement("div"))
);
});
Nothing loads on the screen with this. However when I remove the router I see the App component load:
import React from "react";
import ReactDOM from "react-dom";
import App from "../components/App";
import { Router, Route } from "react-router-dom";
document.addEventListener("DOMContentLoaded", () => {
ReactDOM.render(
<App />,
// <Router>
// <Route path="/">
// <App />
// </Route>
// </Router>,
document.body.appendChild(document.createElement("div"))
);
});
Finally, this is my App component (dont think you need this though)
import React from "react";
const App = () => {
return <div>app has loaded</div>;
};
export default App;
This is built on a Ruby on Rails app, if that matters
if you'are using react-router-dom v5:
import React from "react";
import ReactDOM from "react-dom";
import App from "../components/App";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
document.addEventListener("DOMContentLoaded", () => {
ReactDOM.render(
<Router>
<Switch>
<Route path="/">
<App />
</Route>
</Switch>
</Router>,
document.body.appendChild(document.createElement("div"))
);
});
if you're using react-router-dom v6
import React from "react";
import ReactDOM from "react-dom";
import App from "../components/App";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
document.addEventListener("DOMContentLoaded", () => {
ReactDOM.render(
<Router>
<Routes>
<Route path="/" element={<App />} />
</Routes>
</Router>,
document.body.appendChild(document.createElement("div"))
);
});
Instead of
import { Router, Route } from "react-router-dom";
try
import { BrowserRouter, Route } from "react-router-dom";
What versions of react and react-router-dom are you using? This works for me in a fresh npx create-react-app:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { BrowserRouter, Routes, Route } from "react-router-dom"; // BrowserRouter as Router
document.addEventListener("DOMContentLoaded", () => {
ReactDOM.render(
<div>
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
</Routes>
</BrowserRouter>
</div>,
document.body.appendChild(document.createElement("div"))
);
});
Fixed:
import React from "react";
import ReactDOM from "react-dom";
import App from "../components/App";
import { Router, Route, Switch } from "react-router-dom";
document.addEventListener("DOMContentLoaded", () => {
ReactDOM.render(
<Router>
<Switch>
<Route exact path="/">
<App />
</Route>
</Switch>
</Router>,
document.body.appendChild(document.createElement("div"))
);
});
If you have followed all the steps, then the answer may just be that you installed the NPM package in the wrong place.
Make sure it is in your project folders JSON file.
Considering you're new to React it is pretty easy to install packages in the wrong place.
// this is my index.js
import React, { } from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import store from "./store/configureStore";
import { Router } from "react-router";
import "./index.css";
import App from "./App";
import history from "./history";
// append app to dom
ReactDOM.render(
<Provider store={store}>
<Router history={history}>
<App />
</Router>
</Provider>,
document.getElementById("root")
);
//this is my app.js
import React, { Component } from 'react';
import { Route, Switch, BrowserRouter } from 'react-router-dom';
import Inscription from "../src/pages/inscription";
class App extends Component {
render() {
return (
< BrowserRouter>
<Route exact path="/" component={Inscription} />
</ BrowserRouter>
);
}
}
export default (App);
I am having changing the view in react with routing. It seems I have tried everything I can google with no luck. the page affiche but doesn't load
Please same one can help mee :(
Try removing the BrowserRouter from the App component. You have already provided a Router in index.js. Also in case you want to define multiple routes, you have to use switch
<Switch>
<Route exact path="/" component={Inscription} />
<Route exact path="/hello" component={HelloComponent} />
<Switch>
In my application, I am trying to provide store to Router as shown in below code. but It seems like not working as per expectation. Can anyone suggest me the correct way to do it? I have provided my code below.
index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import store from "./store";
import { Provider } from 'react-redux'
ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById("root"));
App.js
import React, { Component } from "react";
import "./App.css";
import SectionIndicator from "./components/SectionIndicator/SectionIndicator";
import Section from "./components/Section/Section";
import { BrowserRouter as Router, Route, Switch, browserHistory } from "react-router-dom";
import Section2 from "./components/Section/Section2"; import CheckUpButton from "./components/CheckUpButton/CheckUpButton";
import AppContent from "./AppContent";
import createHistory from "history/createBrowserHistory";
class App extends Component {
render() {
const history = createHistory({ basename: '/' });
return (
<Router history={history} >
<div>
<Switch>
<Route path="/" exact component={CheckUpButton} />
<Route path="/assess" exact component={AppContent} />
<Route path="/section2" component={Section2} />
</Switch>
</div>
</Router>
)
}
}
export default App;
error ::
You should call your App component inside your ReactDOM.Render:
ReactDOM.render(<App />, document.getElementById('root'));
Then, wrap your app with the provider component and call your router inside :
<Provider store={store}>
<Router history={history}>
<Routes />
<Router />
<Provider />
Don't forget to pass history to Router component.
Try it this way :)
I am currently experimenting with the use of React Router on the website I am building. I came across the use of React Router in order to navigate through my website, and also do other things like read parameter values etc. However, I find it to be slightly confusing. You see, on my administrator login page, the router only works some times - but I haven't really figured out when and when not. I am using this.props.history.push('/admin/dashboard'), which I believe is the correct way of doing it. This is currently my setup in index.js where i have all my routes:
import React from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from './registerServiceWorker';
import './css-styling/styling.css'
import Frontpage from './Frontpage';
import { BrowserRouter, Route, Router, Switch, Link, NavLink } from 'react-router-dom';
import AdminLogin from './Admin-Login';
import AdminWelcome from './Admin-Welcome';
import Authentication from './components/Authentication';
const websiteRoutes = (
<Router history={history}>
<div>
<Switch>
<Route path="/" component={Frontpage} exact={true}/>
<Route path="/admin" component={AdminLogin} exact={true}/>
<Authentication props={this.props}>
<Route path="/admin/welcome" component={AdminWelcome} exact={true}/>
</Authentication>
</Switch>
</div>
</Router>
);
var appRoot = document.getElementById('root');
registerServiceWorker();
ReactDOM.render(websiteRoutes, appRoot);
And each 'component' has its structure like this:
import React from 'react';
import ReactDOM from 'react-dom';
import AdminHeader from './components/Admin-Header';
import AdminPanelLogin from './components/Admin-Panel-Add-News';
import history from './components/History';
class AdminLogin extends React.Component{
render() {
return(
<div>
<AdminHeader />
<AdminPanelLogin />
</div>
);
}
}
export default AdminLogin;
What seem to be the problem here? I have tried a lot of different solutions, without having any luck. One of them was creating this 'global history', which you can see that I have imported in my AdminAddNews class.
What is the correct way of using React Router in my case?
By the way; The history.push happens inside my AdminPanelLogin component, where the code looks like this:
import React from 'react';
import ReactDOM from 'react-dom';
import { Icon, Input, Button, Message } from 'semantic-ui-react';
import {auth} from './Firebase';
import {NotificationContainer, NotificationManager} from 'react-notifications';
import { withRouter, Redirect } from 'react-router-dom';
import history from './components/History';
class AdminLogin extends React.Component{
constructor(props){
super(props);
this.handleLogin = this.handleLogin.bind(this);
this.clickLogin = this.clickLogin.bind(this);
this.performLogin = this.performLogin.bind(this);
}
handleLogin(e){
this.setState({
[e.target.name]: e.target.value
});
}
clickLogin(e){
e.preventDefault();
auth.signInWithEmailAndPassword(this.state.email, this.state.password).then(() => {
this.props.history.push('/admin/dashboard');
}).catch((error)=> {
})
}
render() {
return (
<HTMLGOESHERE>
);
}
}
export default AdminLogin;
Few things, that you need to correct,
First: In your Routes you have passed history but you have not created a custom history anywhere. You can simply use BrowserRouter for now.
Second: Write your authentication component as Wrapper to your Routes instead of using your Routes as children to it
Authentication:
const PrivateRoute = (props) => {
const userKey = Object.keys(window.localStorage)
.filter(it => it.startsWith('firebase:authUser'))[0];
const user = userKey ? JSON.parse(localStorage.getItem(userKey)) : undefined;
if (user) {
return <Route {...props} />
} else {
return <Redirect to='/admin'/>
}
}
export default PrivateRoute;
Now you Routes can be
import { BrowserRouter as Router, Route, Router, Switch } from 'react-router-dom';
import Authentication from './Authentication';
const websiteRoutes = (
<Router>
<div>
<Switch>
<Route path="/" component={Frontpage} exact={true}/>
<Route path="/admin" component={AdminLogin} exact={true}/>
<Authentication path="/admin/welcome" component={AdminWelcome} exact={true}/>
</Switch>
</div>
</Router>
);
Apart from this check how to Programmatically Navigate with react-router
Actually, you have to use browserHistory, which is a function of react-router.I hope following snippet will help you,
Import react-router in your index.js
import {Router, Route, browserHistory} from 'react-router';
ReactDOM.render(
<Router history={browserHistory} >
<Route path="/admin/somethingZero" component={somethingZero} />
<Route path="/admin/somethingOne" component={somethingOne}/>
</Router> , document.getElementById("root")
)
you can navigate between the components, by using browserHistory.push function
clickLogin(){
browserHistory.push('/admin/dashboard')
}
Also, go on with this tutorial, it will give better understanding of routers.
I am new to reactjs and working to learn redux with react router. I want to have routes as separate file. However somehow its not working because I am not able to pass the dependencies. Following is code details.
Working index.js having routes as well:
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from 'react-redux';
import {ReduxRouter} from "redux-react-router";
import {Route} from "react-router"
import createBrowserHistory from "history/lib/createBrowserHistory"
import configureStore from './store';
import App from "./containers/App";
import Home from "./components/Home";
import Countries from "./components/Countries";
import {fetchData} from './actions/actions';
const history = new createBrowserHistory();
const store = configureStore();
function loadData() {
store.dispatch(fetchData('https://restcountries.eu/rest/v1/all'))
}
ReactDOM.render(
<Provider store={store}>
<ReduxRouter>
<Route history={history}>
<Route component={App}>
<Route path='/' component={Home} />
<Route path='/countries' component={Countries} onEnter={loadData} />
</Route>
</Route>
</ReduxRouter>
</Provider>,
document.getElementById('root')
);
Following is the code which I tried to split as separate routes.js
index.js
import 'babel-core/polyfill';
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from 'react-redux';
import {ReduxRouter} from "redux-react-router";
import {Route} from "react-router"
import createBrowserHistory from "history/lib/createBrowserHistory"
import configureStore from './store';
import routes from "./routes";
import {fetchData} from './actions/actions';
const history = new createBrowserHistory();
const store = configureStore();
ReactDOM.render(
<Provider store={store}>
<ReduxRouter>
<Route history={history} routes={routes}>
</Route>
</ReduxRouter>
</Provider>,
document.getElementById('root')
);
routes.js
import React from "react";
import { Provider } from 'react-redux';
import {ReduxRouter} from "redux-react-router";
import {Route} from "react-router"
import App from "./../containers/App";
import Home from "./../components/Home";
import Countries from "./../components/Countries";
const router =
<Route history={history}>
<Route component={App}>
<Route path='/' component={Home} />
<Route path='/countries' component={Countries} onEnter={loadData} />
</Route>
</Route>;
export default router;
However it is throwing error as not able to identify loadData function.
Please help.
Pass it as a child, note the parent is called Router:
<Router history={history}>
{routes}
</Router>
Also Route doesn't take the history prop, Router does.
See an example of Router.js and Route.js on a starter of mine: https://github.com/DominicTobias/universal-react/tree/master/app
After following the answer given by Dominic I changed my code as below to pass the dependency as function argument as I don't want to create the store object again. Now its working fine. Following is modified code.
index.js
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from 'react-redux';
import {ReduxRouter} from "redux-react-router";
import {Route} from "react-router"
import createBrowserHistory from "history/lib/createBrowserHistory"
import configureStore from './store';
import App from "./containers/App";
import Home from "./components/Home";
import Countries from "./components/Countries";
import {fetchData} from './actions/actions';
import routes from "./routes";
const history = new createBrowserHistory();
const store = configureStore();
function loadData() {
store.dispatch(fetchData('https://restcountries.eu/rest/v1/all'))
}
ReactDOM.render(
<Provider store={store}>
<ReduxRouter>
<Route history={history}>
{routes(loadData)}
</Route>
</ReduxRouter>
</Provider>,
document.getElementById('root')
);
routes.js
import React from "react";
import { Provider } from 'react-redux';
import {ReduxRouter} from "redux-react-router";
import {Route} from "react-router"
import App from "./../containers/App";
import Home from "./../components/Home";
import Countries from "./../components/Countries";
function router(loadData) {
return (<Route component={App}>
<Route path='/' component={Home} />
<Route path='/countries' component={Countries} onEnter={loadData} />
</Route>);
}
export default router;