How to refresh page with React Router? - reactjs

I would like to refresh page on click using React Router.
I know, I could use window.location.reload();
But I would like to use some magic from React Router. There is a way to refresh page with React Router or should I use a normal method from window object?

If you are using react-router v6 then try this (take this as an example), it might works!
import { useNavigate } from "react-router-dom";
const navigate = useNavigate();
const refreshPage = () => {
navigate(0);
}
If you are using old then try this!
Just put that attribute on your Router, and whenever you are on a new Path it will force the page to reload itself.
<Router forceRefresh={true}>

Related

Move from login page to dashboard after successful login in react js

using React js I am trying to move from login page to dashboard page but i am not getting the correct way.
Find an example for authorization flows with react-router-dom here:
https://github.com/remix-run/react-router/tree/main/examples/auth
Are you using router? If yes, you can use useNavigate in react-router-dom to navigate to another path when you've done login
Ex:
import {useNavigate} from 'react-router-dom'
...
export default function App(){
const navaigate = useNavigate()
const handleLogin = () => {
//do something
...
navigate('/dashboard') //or whatever path you wish
}
return (
....
)
}
Note: It is only working if your React App using Router
Please refer https://github.com/VickyDhanwani/ReactJS-App/blob/main/src/App.js if you are not using react router. Navigation is based on state and update in state changes the view after validation.

Keep redux state on route change

I have react-redux and react-router in my webapp and im trying to change the route while keeping the redux state. I tried all of these and they all removed the redux state:
props.history.push({ pathname: `/my-path`}); // did this using withRouter and useHistory
<Link to={'/my-path'} />cool link</Link>
What am I doing wrong and how can I keep the state? (The reason I can't keep it in localStorage is because when the user closes that page, then the data should go away)
Redux doesn't preserve the state once you refresh the website. If you want to persist data you should use localStorage, and use the event window.onunload to clean it once your browser or page is closed.
Check out this gist
Alternatively, you can pass data when you navigate programatically just like this
import { useHistory } from 'react-router-dom'
...
function myComponentA() {
const history = useHistory()
const navigate = () => {
history.push('/pageB', {
id: 7,
name: 'Dan'
color: 'Red'
})
}
return <button onClick={navigate}>Go to page B</button>
}
...
In component B, use the hook useLocation() and then access the state property, and you should see your data right there.
import { useHistory } from 'react-router-dom'
...
function myComponentB() {
const location = useLocation()
return <h1>{location.state.name}</h1>
}
...
What calls my attention is that if you are using react-router-dom, the link button should preserve the state in your redux store. The data is only cleaned once your browser reloads. Check this sample using hooks and redux-toolkit, which could be the real solution for your problem. Once you navigate to the component B the state should persist.
For more documentation see
Redux Toolkit: https://redux-toolkit.js.org/
react-router-dom: https://reactrouter.com/web/guides/quick-start

BrowserRouter vs Router with history.push()

I am trying to understand the difference between BrowserRouter and Router of the react-router-dom (v5) package and what difference it makes for my example below.
The documentation says:
BrowserRouter
A that uses the HTML5 history API (pushState,
replaceState and the popstate event) to keep your UI in sync with the
URL.
Source: https://reacttraining.com/react-router/web/api/BrowserRouter
Router
The common low-level interface for all router components. Typically
apps will use one of the high-level routers instead: BrowserRouter, HashRouter, MemoryRouter, NativeRouter, StaticRouter
Source: https://reacttraining.com/react-router/web/api/Router
From what I understand is that I should be using BrowserRouter for my HTML5 browser apps and I have been doing this so far.
history.push(...) example:
I am trying to perform a history.push('/myNewRoute') within a thunk:
import history as './history';
...
export function someAsyncAction(input) {
return dispatch => {
fetch(`${API_URL}/someUrl`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({ input }),
}).then(() => {
history.push('/myNewRoute');
}).catch((err) => {
dispatch(setError(err));
})
};
};
history is defined as this module:
import { createBrowserHistory } from 'history';
export default createBrowserHistory();
and the history is also passed to my router:
import { BrowserRouter as Router } from 'react-router-dom';
import history as './history';
...
const App = () => (
<Router history={history}>
...
</Router>
);
Problem: history.push() will update the URL in the browser bar but not render the component behind the route.
If I import Router instead of BrowserRouter, it works:
// Does not work:
import { BrowserRouter as Router } from 'react-router-dom';
// Does work:
import { Router } from 'react-router-dom';
BrowserRouter ignores the history prop as it handles the history automatically for you. If you need access to the history outside of a react component, then using Router should be fine.
You can access history via the useHistory hook let history = useHistory(); to perform history.push() for BrowserRouter.
Looking at the HTML5 History API documentation, it seems that the history API preserves state for the user automatically. Say you are at page 1 initially and page 1 has a page outlook A. You performed some actions that changes the page 1 outlook to B. If you now moves to page 2, when you click the back button on the browser, you will be direct back to page 1. History API preseves your state so it knows to render outlook B to you, so that is the advantage of using BrowserRouter. Though I am not 100% sure, I suppose Browser doesn't come with this functionality and in which case it will render outlook A when you get directed back to page 1. This is not true. I am not sure about the difference.
I have the same issue.
BrowserRouter and useHistory() hook have been used for my component. And createBrowserHistory() has been used for redux-saga. But, the page has not moved by redux-saga such as your case.
Adding to that, my source has been developed using BrowserRouter, I don't want to replace it to Router component.
As my poor investigating, I found that both history objects are different. (I compared them with if and ==.) I guess it is the reason.
To solve it, I save the reference of the history object got by useHistory() to some global utility code, and use it in redux-saga code. Then, it works well.
I don't think this is the best way, but I couldn't find the best and official way yet.

Is it possible to change route on scroll?

I want to load multiple components on a single page and have different routes for all of them. For example i hit a route /article/1 and it loads a component, after scrolling through completely through that article i want the route to change to /article/2 and the corresponding article to load. I am using react and react router, basically i want 4 (article/3 , article/4) articles on a page and all these should be scrollable with the route changing as i scroll onto a particular article. How can i achieve this using react and react-router?
use react-perfect-scrollbar package from npm.
index.js (main entry point of your application) add this css
import 'react-perfect-scrollbar/dist/css/styles.css';
your component file where you want on scroll change url
import PerfectScrollbar from 'react-perfect-scrollbar';
import { Redirect } from 'react-router-dom';
handleScroll = () => {
<Redirect to="/article/2" />
}
<PerfectScrollbar onYReachEnd={this.handleScroll}> // when you reach then end of screen it's call handleScroll function and redirect to other url.so based on your requirements you can pick up from here.
// your articles code..
</PerfectScrollbar>

Automatic redirect after login with react-router

I wanted to build a Facebook login into my react/react-router/flux application.
I have a listener registered on the login event and would like to redirect the user to '/dashboard' if they are logged in. How can I do that? location.push didn't work very well, except after reloading the page completely.
React Router v3
This is what I do
var Router = require('react-router');
Router.browserHistory.push('/somepath');
React Router v4
Now we can use the <Redirect>component in React Router v4.
Rendering a <Redirect> will navigate to a new location. The new location will override the current location in the history stack, like server-side redirects.
import React, { Component } from 'react';
import { Redirect } from 'react-router';
export default class LoginComponent extends Component {
render(){
if(this.state.isLoggedIn === true){
return (<Redirect to="/your/redirect/page" />);
}else{
return (<div>Login Please</div>);
}
}
}
Documentation https://reacttraining.com/react-router/web/api/Redirect
React Router v0.13
The Router instance returned from Router.create can be passed around (or, if inside a React component, you can get it from the context object), and contains methods like transitionTo that you can use to transition to a new route.
React Router v2
Even though the question is already answered, I think it's relevant to post the solution that worked for me, since it wasn't covered in any of the solutions given here.
First, I'm using the router context on my LoginForm component
LoginForm.contextTypes = {
router: React.PropTypes.object
};
After that, I can access the router object inside my LoginForm component
handleLogin() {
this.context.router.push('/anotherroute');
}
PS: working on React-router version 2.6.0
React Router v3
Navigating Outside of Components
create your app with Router like this
// Your main file that renders a <Router>:
import { Router, browserHistory } from 'react-router'
import routes from './app/routes'
render(
<Router history={browserHistory} routes={routes} />,
mountNode
)
Somewhere like a Redux middleware or Flux action:
import { browserHistory } from 'react-router'
// Go to /some/path.
browserHistory.push('/some/path')
// Go back to previous location.
browserHistory.goBack()
react-router/tree/v3/docs
React Router v4.2.0
I am using React-16.2.0 & React-router-4.2.0
And I get solution by this code
this.props.history.push("/");
My working code:
.then(response => response.json())
.then(data => {
if(data.status == 200){
this.props.history.push("/");
console.log('Successfully Login');
}
})
I was following this document redirect-on-login-and-logout
I was also try by return <Redirect to='/' /> But unlucky, this not working for me.
React router v5 using hooks
These steps are for authorisation redirect. But can be used for login/logout redirection also.
The <Redirect/> accepts to prop as a string or an object. We can utilise the object to pass the redirection path after login/logout using hooks easily.
Get the pathname of url from where the <Redirect/> is called using
useLocation()
const {pathname} = useLocation()
In the to prop of <Redirect/> pass in the following object:
<Redirect to={{pathname:'/login',state: {referrer: pathname}}/>
In the Login component access the route state variable using useLocation() hook and use the useHistory() hook to redirect after successful login.
const history = useHistory();
const location = useLocation();
const login() => {
// After login success
const {state: {referrer}} = location;
history.push(referrer)
};
Check the official docs here
React Router v3
Navigating inside components
You should use withRouter decorator when it's necessary to redirect inside a component. The decorator uses context instead of you.
import {withRouter} from 'react-router'
fucntion Foo(props) {
props.router.push('/users/16');
}
export default withRouter(Foo);
withRouter(Component, [options])
A HoC (higher-order component) that wraps another component to enhance
its props with router props.
withRouterProps = {
...componentProps,
router,
params,
location,
routes
}
Pass in your component and it will return the
wrapped component.
You can explicit specify router as a prop to the wrapper component to
override the router object from context.
In your store:
data.router.transitionTo('user');
And router has:
"Route name="user" handler={User}"
User is route handler

Resources