How can I access previous path in React using BrowserRouter? - reactjs

Can I find previous paths in the history object? E.g. I go to "/activity/55" from "/home". Can I get the string "/home" somehow when I'm in the component for "/activity/55"?
history.goBack() works and takes me back to "/home" so the information is in there?
Or am I trying to do this the wrong way. I've seen some passing the previous path to each component. Ideally I'd like avoid tracking it manually.

I'm pretty sure that you can't: history.goBack is a tiny wrapper around window.history.go(-1). So the browser's native History object is what actually tracks it, vs the history wrapper used in react-router, and History doesn't expose the actual history stack state.

Related

In React, how do you properly programmatically navigate to a new route/page?

I've been trying to find a straight answer to this and even after searching StackOverflow, I can't find a correct answer for the current version of React.
In my case, I have the following scenario-- the user sets up their data, they post it to the server and within my Save() method, if the save operation is successful, I want to redirect them to the root home page.
Much of the documentation I've found mentions using this.props.history.push(...) to push the new route. However, something has changed with React 4.0.0+ and now history is undefined on the props page.
I am not necessarily interested in pushing the new route to the history object if that is a deprecated way of routing to another page. However, all of the more current examples I've found talk about setting up routes and links within the JSX. That's fine, but I've yet to find a way to programmatically redirect the page un certain code conditions.
Apologies if there is an answer out this already, but I haven't found a straight answer.
The route props are only given to the components that are used for the component or render props of the Route components.
If you want to use the route props in any other component in your app, you need to pass the props manually or use the withRouter HOC.
import { withRouter } from "react-router-dom";
// ...
export default withRouter(MyComponent);
You have to connect this component with router. To connect you have to use withRouter.
export default withStyles(commonModalStyle)(withRouter(connect(mapStateToProps, mapDispatchToProps)(NewOrUpdateModal)));
Please refer this

Accessing redux state in new tabs/windows

I am using redux to store my state. It works properly when i navigate to the same page (multiple components but on a single page). But when I open in a link in new tab/window, the state becomes undefined.
Based on findings, the redux state is expected to reset when refreshing a page or opening in new tab/window. What I then thought of is to pass store.getState() as a param when navigating to another component so that if the component sees that the state is undefined, it will access its props state (passed on by the previous component).
Now, when a link is opened in new tab, I need to pass the state. I am using react-router for navigation. Currently, the state is passed onto other page when I just click on the link. But when I open the link in new window/tab, the state, again, becomes undefined. I'm using this to navigate to the specified link:
<Link to={link}>{value}</Link>
where link is a const containing the pathname and state(store.getState()) I need to pass.
I have found many similar stackoverflow questions[e.g. programmatically-navigate-using-react-router]. I've tried using
<a onClick={history.push(link)}>
but it doesn't seem to work. Maybe I'm using it the wrong way. The other ones I just can't figure out how to use/implement in this context.
Please give sample code snippets aside from just explaining. I'm quite a beginner in redux/react.
Thanks!
The first thing that you should check is that you are using the correct version of React-Router. I am unsure if that approach will work in anything besides V4.
If you are indeed using React-Router V4 and it still doesn't work. Another cleaner approach you can take that will save the state not only after redirects to new tabs/windows but also after refreshes, is to save the state of your application in the local storage.
This video by Dan Abramov explains how to do it.

React Router: retaining state of previously visited "route"s

I have a React application (that uses React Router) with five "routes"/sub-pages.
If the user enters information on a sub-page (e.g. checks a checkbox/enters text in an input field on the page), then visits another sub-page, and goes back to the previous sub-page, I want that sub-page to have retained the state the user left it in.
I also need to be able to retrieve the state of all sub-pages, at some point.
Is this possible/viable using React Router, or is there a better way to do it?
If you didn't want to use Redux or similar to maintain data between route changes, you could always have a wrapping component that sits above <Router> and passes data down to each relevant <Route> via react-routers render prop solution. You would need to provide callbacks for each update that a sub-section might need to make however, which isn't necessarily scalable.
Alternatively, another method is to take the state of the sub-section away from the component and into the URL via parameters, for example search filters that you might commonly see in URLs. However this isn't always desirable.
Implementing Redux would be a far better solution to the problem though.

What is the use of Redux-Router in addition to reac-router?

guys. When I go through the documentation of redux-router, I just cannot understand why do we need it?
Here is what the documentation is trying to explain:
React Router is a fantastic routing library, but one downside is that
it abstracts away a very crucial piece of application state — the
current route! This abstraction is super useful for route matching and
rendering, but the API for interacting with the router to 1) trigger
transitions and 2) react to state changes within the component
lifecycle leaves something to be desired.
It turns out we already solved these problems with Flux (and Redux):
We use action creators to trigger state changes, and we use
higher-order components to subscribe to state changes.
This library allows you to keep your router state inside your Redux
store. So getting the current pathname, query, and params is as easy
as selecting any other part of your application state.
As far as I can understand, it is trying to say redux router can keep router state inside redux store so that we can get route info more conveniently.
But within react-router, I can also easily do it.
Like path="messages/:id", I can use this.props.params.id to get the params.
Can someone explain in what scenario redux-router bring its benefit?
Redux (and in general, the flux pattern) is all about having the entire application state stored in one central place. This has the benefit of easier debugging and makes it easier to implement certain features.
If you've ever used the redux-devtools in a react app with react-router, you'll notice that its only of limited use, because you can't replay the entire lifecycle of the application. When the user changes routes, that's not recorded in the redux store. Redux Router keeps the route state in the store.
You could use this for debugging, you could serialise the entire store history and log it elsewhere to replay user sessions. You could hook into it to implement full undo, or log analytics events.
redux-simple-router is a library which could help you understand how to use react router in a redux application.
It is a very simple library stores the URL in redux state and keeps it in sync with any react-router changes.
redux-simple-router compared to redux-router is:
Much smaller and simpler. You don't need to learn another library on top of everything else.
Encourages direct access of react-router APIs. Need server-side rendering, or something else advanced? Just read react-router's docs.
Only stores the current URL and state, whereas redux-router stores the entire location object from react-router.
Follow one of the these 2 examples to get up and running:
redux-simple-router-example
redux-frontend-boilerplate

Disable history and URL state while using React Router

Any quick-and-easy answer to the scenario where you want to build something like a simple questionnaire with React and React Router where you don't want the user to be able to modify the URL to browse anywhere and you also don't want to push history state into the browser, essentially preventing use of the back button?
Sample routes might look like:
questions/1
questions/2
questions/3
...so on
But the URL should stay the same at all times and the history won't change, essentially what a single page app without routing would behave like.
For the history part, you would need to use replaceWith() everywhere you want to change route.
If you're using <Link>, you could create your own version which uses replaceWith instead of transitionTo - you should just be able to copy its implementation and replace the PropTypes require call with require('react-router/lib/PropTypes').
I can't immediately think of a non-horrible way to prevent the user from jumping around though - presumably you also want the app to break if they try to start on anything but the base URL? I would just use some simple state to control which component is currently being rendered instead of using React Router if that's the behaviour you really want.

Resources