When you click on the button, the url changes but the redirect does not occur. If you reload manually, then it opens the desired page. Tell me how to fix this problem.
I suspect the problem is with router and history communication.
ROUTE.JS
import React, {Component} from "react";
import Cookies from "universal-cookie";
import history from "../../history";
const {SubMenu} = Menu;
export default class Sider extends Component {
outUser = () => {
const cookies = new Cookies();
cookies.remove("jwt", { path: '/' });
history.push("/");
}
render() {
return (
<div>
<Button onClick={this.outUser}>Выйти</Button>
</div>
);
}
}
APP.JS
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route
} from "react-router-dom";
import history from "./history";
import Auth from "./pages/auth/component"
import HomePage from "./pages/home/component";
import Cookies from 'universal-cookie';
const cookies = new Cookies();
function App() {
return (
<Router history={history}>
<Switch>
<Route exact component={Auth} path="/" />
<div className="App">
<div className="pages">
<Route component={HomePage} path="/home"/>
</div>
</div>
</Switch>
</Router>
);
}
Related
I created a AdminProtectedRoute.js inside my frontend that will make sure only admin users will have access to these routes.
AdminProtectedRoute.js
[import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";
const AdminProtectedRoute = (props) => {
let MyRender = props.MyRender;
const staff = JSON.parse(localStorage.getItem("staff"));
const history = useNavigate();
const staffRole = staff.role;
useEffect(() => {
if (staffRole !== "admin") {
history.push("/");
}
});
return (
<div>
<MyRender />
</div>
);
};
export default AdminProtectedRoute;][1]
Inside my App.js calling this route protector.
App.js
import {BrowserRouter as Router, Route, Routes} from 'react-router-dom'
import Login from '../src/pages/LoginPage';
import AddStaff from './pages/Admin/AddStaff';
import AdminProtectedRoute from './AdminProtectedRoute';
function App() {
return (
<div className="App">
<Router>
<Routes>
<Route path = "/" element={<Login/>}/>
<Route path = "/add" element= {<AdminProtectedRoute MyRender={<AddStaff/>}/>}></Route>
</Routes>
</Router>
</div>
);
}
export default App;
Error messages
I'm trying to navigate to a link /login, when I click the actual link I can see the url change in the browser but the Login component isn't loaded:
// App.tsx
import React from 'react';
import {BrowserRouter as Router, Route} from 'react-router-dom';
import Header from './components/Header/Header';
import Login from './components/Login/Login';
const App = () => {
return (
<React.Fragment>
<Header />
<Router>
<Route path="/login" exact component={Login} />
</Router>
</React.Fragment>
);
};
export default App;
// Header.tsx
import React from 'react';
import {BrowserRouter, Link} from 'react-router-dom';
const Header = () => {
return (
<BrowserRouter>
<Link to="/login">login</Link>
</BrowserRouter>
);
};
export default Header;
And the actual login component:
// Login.tsx
import React from 'react';
// import {useHistory} from 'react-router-dom';
const Login = () => {
console.log('login component opened');
return (
<div>
Login
</div>
);
};
export default Login;
When I click the link in the header component I get navigated to http://localhost:8080/login but the component isn't loading. Also if I refresh that page http://localhost:8080/login I get a message:
Cannot GET /login
First, the Link component needs to be inside BrowserRouter
const App = () => {
return (
<React.Fragment>
<Router>
<Header />
<Route path="/login" exact component={Login} />
</Router>
</React.Fragment>
);
};
Also, you don't need to wrap BrowserRouter around Link component:
import React from 'react';
import {BrowserRouter, Link} from 'react-router-dom';
const Header = () => {
return (
<Link to="/login">login</Link>
);
};
export default Header;
Try this
const Header = () => {
return (
<BrowserRouter>
<Link to="/login">login</Link>
<Switch>
<Route exact path="/login">
<Login />
</Route>
</Switch>
</BrowserRouter>
);
};
Inside App.tsx your import shouldn't look like this:
import Login from './components/Login/login';
It should be like this instead:
import Login from './components/Login/Login';
You used a wrong file name for the Login component. The first letter must be uppercase.
I'm using the react-router-dom Link component to manage my navigation but it doesn't work.
The Link changes the URL but doesn't render the component.
Here is a simple app describing my problem. I'm trying to use My App header as go home link:
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import React from 'react';
const Navigation = () => {
return (
<div>
<Link to="/events">
<h1>My Application</h1>
</Link>
</div>
);
};
const ConnectedNavigation = connect((state) => state)(Navigation);
export default ConnectedNavigation;
App.jsx code :
import React from 'react';
import { Provider } from 'react-redux';
import { store } from '../store/index';
import ConnectedDashboard from './Dashboard';
import ConnectedEventDetails from './EventDetails';
import { Router, Route } from 'react-router-dom';
import { history } from '../store/history';
import ConnectedNavigation from './Navigation';
export const Main = () => (
<Router history={history}>
<Provider store={store}>
<div>
<ConnectedNavigation />
<Route exact path="/events" render={() => <ConnectedDashboard />} />
<Route
exact
path="/event/:id"
//match prop is necessary in order to determine which event
//we are looking for
render={({ match }) => <ConnectedEventDetails match={match} />}
/>
</div>
</Provider>
</Router>
);
As you can see i added exact on my Routes to avoid any confusions
This problem comes from this line:
import { Router, Route } from 'react-router-dom';
The correct import is :
import { BrowserRouter as Router, Route } from 'react-router-dom';
I am trying to add the live website URL i.e "https://covid19statswebsite.netlify.app/" so that when I click on my Button it should redirect me to the above URL. How can I do that?
Any Suggestions?
below is my Button,
import React from "react";
import "./Banner.css"
import BannerVideo from './videos/video-2.mp4'
import {Button} from "react-bootstrap";
import {useHistory} from "react-router-dom";
// import axios from './axios'
// import requests from "./Request";
function Banner(){
const history = useHistory()
return(
<div className="banner-container">
<video src={BannerVideo} autoPlay loop muted/>
<h1>ADVENTURE AWAITS</h1>
<p>What are you waiting for?</p>
/////////// Button That needs to redirect it ///////////////////////////////////////////////////////
<div className="banner-buttons">
<br/><br/><Button onClick={() => history.push("/covid")} className="covid"><span>COVID-19 Status</span></Button>
</div>
</div>
);
}
export default Banner
This is my App.js file which imports the Banner.js file above for Routes. I am not sure that the thing I want will happen with Routes or not. So I'd really love to know any other alternative if present.
import React, {useEffect} from 'react';
import './App.css';
import HomeScreen from "./screens/HomeScreen";
import LoginScreen from "./screens/LoginScreen";
import ProfileScreen from "./screens/ProfileScreen"
import {auth} from "./firebase";
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom';
import {useDispatch, useSelector} from "react-redux";
import {login, logout, selectUser} from "./features/userSlice";
import Spain from "./countries/Spain";
import Covid from './Covid.js'
function App() {
const user = useSelector(selectUser)
const dispatch = useDispatch();
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(userAuth => {
if (userAuth){
dispatch(login({
uid: userAuth.uid,
email: userAuth.email
}))
}else {
dispatch(logout());
}
});
return unsubscribe
}, [dispatch]);
return (
<div className="App">
<Router>
{!user ? (
<LoginScreen/>
):(
<Switch>
<Route path="/profile">
<ProfileScreen/>
</Route>
<Route exact path="/">
<HomeScreen/>
</Route>
<Route path="/spain">
<Spain/>
</Route>
//////////////////// Covid part //////////////////////////////////////////////////////////
<Route path="/covid">
<Covid/>
</Route>
</Switch>
)}
</Router>
</div>
);
}
export default App;
Below is the Covid.js which I created to check whether the Route works or not.
import React from "react";
function Covid(){
return(
<div className="covid">
<h1>hello</h1>
</div>
)
}
export default Covid
Edit:
import { Link } from "react-router-dom";
<Link
to={{
pathname:
"https://.......",}}
target="_blank">
<Button>...</Button>
</Link>
try to put the link in a hyperlink.
<a
href="https://covid19statswebsite.netlify.app/"
target="_blank">
<Button>...</Button>
</a>
I have a login react class that after passed authentication and successfully authenticated to page should take me to admin page but in this situation it just change URL to admin page after successful sign in or sign out but doesn't show any new admin component at all. I am using react-router v4 and this app don't work with it quite well. Here is My components
Maybe there is any way to solve this problem. I used high order component withRouter that should solve this problem but it doesn't do anything. I have no errors in console.
Sign In
import React, {Component} from 'react';
import {connect} from 'react-redux';
import {reduxForm, Field} from 'redux-form';
import {withRouter} from 'react-router-dom';
import * as actions from '../../actions/signin_user';
class SignIn extends Component {
handleFormSubmit({email, password}) {
this.props.signinUser({email, password});
}
renderAlert() {
if (this.props.errorMessage) {
return (
<div className="alert alert-danger">
<strong>Oops! Błąd logowania, kod błędu: {this.props.errorMessage}</strong>
</div>
)
}
}
render() {
const {handleSubmit, fields: {email, password}} = this.props;
return (
<form onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
<fieldset className="form-group">
<label>Adres Email:</label>
<Field {...email} name="email" type="text" className="form-control" component="input"/>
</fieldset>
<fieldset className="form-group">
<label>Hasło:</label>
<Field {...password} name="password" type="password" className="form-control" component="input"/>
</fieldset>
{this.renderAlert()}
<button action="submit" className="btn btn-primary">Zaloguj się</button>
</form>
)
}
}
function mapStateToProps(state) {
return {errorMessage: state.auth.error}
}
SignIn = reduxForm({form: 'SignIn', fields: ['email', 'password']})(SignIn);
export default withRouter(connect(mapStateToProps, actions)(SignIn));
Admin Page
/**
* Created by konraduciechowski on 26.08.2017.
*/
import React, {Component} from 'react';
import {Link} from 'react-router-dom';
class AdminPage extends Component {
render() {
return (
<div className="header-stick">
{/*IMPORTANT ADD FUNCTION TO NOT ABLE EVERYONE TO GET TO ADMIN PAGE
WHEN THEIR NOT ADMIN*/}
{/*NEED TO FIX ROUTES FOR ADMIN PAGE*/}
<ul className="admin-menu">
<li className="admin-menu-item">
<Link to="/panel+administracyjny/kalendarz">Kalendarz</Link>
</li>
<li className="admin-menu-item">
<Link to="/panel+administracyjny/blog">Blog</Link>
</li>
<li className="admin-menu-item">
<Link to="/panel+administracyjny/pracownik">Zarządzanie pracownikami</Link>
</li>
</ul>
</div>
)
}
}
export default AdminPage;
redux action
/**
* Created by konraduciechowski on 16.10.2017.
*/
import axios from 'axios';
import history from '../helpers/history';
import {AUTH_USER, AUTH_ERROR, UNAUTH_USER} from './types'
const ROOT_DEV_API = 'http://salonenface.dev/api/';
const ROOT_PROD_API = 'https://salonenface.pl/api/';
const ROOT_TEST_API = 'http://localhost:3090';
export function signinUser({email, password}) {
return function (dispatch) {
//Submit password n' email to server
axios.post(`${ROOT_TEST_API}/signin`, {email, password})
.then(response => {
// if request is good...
// Update state to indicate user is authenticated
dispatch({type: AUTH_USER});
// Save JWT token
localStorage.setItem('token', response.data.token);
// redirect to admin route section
history.push("/panel+administracyjny");
})
.catch((error) => {
///////////////////////////////////////////
// if request is bad...
// show error to user
dispatch(authError(error.response.status));
})
}
}
export function signupUser({email, password}) {
return function (dispatch) {
axios.post(`${ROOT_TEST_API}/signup`, {email, password})
.then(response => {
dispatch({type: AUTH_USER});
localStorage.setItem('token', response.data.token);
history.push('/panel+administracyjny');
})
.catch(error => dispatch(authError(error.response.data.error)))
}
}
export function authError(error) {
return {
type: AUTH_ERROR,
payload: error
}
}
export function signoutUser() {
localStorage.removeItem('token');
return {type: UNAUTH_USER}
}
EDIT:
Router.js
//React imports
import React, {Component} from 'react';
import {
BrowserRouter as Router,
Route,
Switch,
Redirect,
withRouter
} from 'react-router-dom';
//Redux imports
import {Provider} from 'react-redux';
import {createStore, applyMiddleware} from 'redux';
import promise from 'redux-promise';
import reduxThunk from 'redux-thunk';
//Css imports
import '../styles/App.css';
import '../styles/Admin.css';
import '../../node_modules/bootstrap/dist/css/bootstrap.css';
import '../../node_modules/font-awesome/css/font-awesome.css';
import '../../node_modules/react-big-calendar/lib/css/react-big-calendar.css';
//Page Components imports
import Header from './SiteElementsComponents/Header';
import About from './MainComponents/About';
import Blog from './MainComponents/Blog';
import BlogPost from './MainComponents/BlogPost';
import Contact from './MainComponents/Contact';
import Home from './MainComponents/Home';
import Order from './CalendarComponents/Order';
import Services from './MainComponents/Services';
import Login from './AuthComponents/Login';
import Register from './AuthComponents/Register';
import Footer from './SiteElementsComponents/Footer';
import OrderComplete from './CalendarComponents/OrderComplete';
import SignIn from './AuthComponents/SignIn';
import SignOut from './AuthComponents/SignOut';
import SignUp from './AuthComponents/SignUp';
//Admin Components imports
import AdminPage from './AuthComponents/AdminComponents/AdminPage';
import AdminCalendar from './AuthComponents/AdminComponents/AdminCalendar';
import AdminBlog from './AuthComponents/AdminComponents/AdminBlog';
import AdminBlogNewPost from './AuthComponents/AdminComponents/AdminBlogNewPost';
import AdminBlogShowPost from './AuthComponents/AdminComponents/AdminBlogShowPost';
import AdminEmployee from './AuthComponents/AdminComponents/AdminEmployee';
import AuthExample from './TestComponents/AuthExample';
//Redux reducers
import reducers from '../reducers';
//History
import history from '../helpers/history';
//Middleware
const createStoreWithMiddleware = applyMiddleware(promise, reduxThunk)(createStore);
const App = () => {
return (
<Provider store={createStoreWithMiddleware(reducers)}>
<div>
<div className="col-xs-12">
<Router history={history}>
<div>
<Header/>
<div className="container background-block">
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/o+nas" component={About}/>
<Route path="/aktualnosci" component={Blog}/>
<Route path="/post/:id" component={BlogPost}/>
<Route path="/kontakt" component={Contact}/>
<Route path="/uslugi" component={Services}/>
<Route path="/logowanie" component={Login}/>
<Route path="/signin" component={SignIn}/>
<Route path="/wylogowanie" component={SignOut}/>
<Route path="/signup" component={SignUp}/>
<Route path="/rejestracja" component={Register}/>
<Route path="/wizyta+zapisana" component={OrderComplete}/>
{/*Calendar options*/}
<Route path="/wizyta+zapisana" component={OrderComplete}/>
<Route path="/wizyta" component={Order}/>
</Switch>
{/*test options*/}
<Route exact path="/AuthExample" component={AuthExample}/>
{/*/!*admin options*!/*/}
<Switch>
<Route exact path="/panel+administracyjny" component={AdminPage}/>
<Route path="/panel+administracyjny/kalendarz" component={AdminCalendar}/>
{/*admin blog options*/}
<Route path="/panel+administracyjny/blog" component={AdminBlog}/>
<Route path="/panel+administracyjny/post/nowy" component={AdminBlogNewPost}/>
<Route path="/panel+administracyjny/pokaz+post/:id"
component={AdminBlogShowPost}/>
{/*admin employee options*/}
<Route path="/panel+administracyjny/pracownik" component={AdminEmployee}/>
</Switch>
</div>
</div>
</Router>
<Footer/>
</div>
</div>
</Provider>
);
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/Router';
import registerServiceWorker from './registerServiceWorker';
import './styles/index.css';
ReactDOM.render(<App />, document.getElementById('app'));
registerServiceWorker();
You can not pass a history to a <BrowserRouter>, as it creates its
own history object
If you are creating your own history Object use <Router> instead of <BrowserRouter> and then pass history object
Import { Router } from 'react-router-dom'
<Router history={history}> <Router/>
You can read more on react-router v.4