I am getting an error
_reactNavigation.NavigationActions.push is not a function
when trying to navigate to same route.
I am applying the accepted solution from below link
React-Navigation go to same route with different params
Related
I'm (obviously) fairly new to ReactJS. I'm using Router v6 for navigation between pages. I have a case where the action of a button on Component A must depend on which component (B or C or ...) launched the page. But, using useNavigate, it doesn't seem to be possible to send a function to the target component A, only text fields seem to be allowed in the object. That is, the following doesn't work:
let navigate = useNavigate()
function nextClick() {
navigate('/UserProfile', {state:{
okClick: userProfileOkClick,
cancelClick: backButtonClick
}})
}
That is, I want to navigate to the UserProfile component, and pass the callback functions its buttons should use. It doesn't work -- in the UserProfile page, the state object is null.
So is there a way to navigate to a new page and dynamically change the button callbacks? I hope so...
Thanks!
Is it possible to use Gatsby's navigate function to navigate to the same page?
For instance, I built a search component that lives on the navigation bar, therefor accessible on any page. Once users perform search, they get routed to the Search Results page via navigate(/search-results).
If they are on that page, and want to perform the search again, that navigate function does not work, hence no results display.
I'm aware I could do a window.location.reload() but wanted to see if there are other ways.
Gatsby's navigation (Link component or navigate function) doesn't support parameters per se as you want to.
From Gatsby's docs:
Neither <Link> nor navigate can be used for in-route navigation with a
hash or query parameter. If you need this behavior, you should either
use an anchor tag or import the #reach/router package—which Gatsby
already depends upon—to make use of its navigate function, like so:
So, that said, you have two approaches:
Importing the navigation from #reach/router:
import { navigate } from '#reach/router';
onClick = () => {
navigate('?foo=bar');
}
Using window.location as you pointed
Of course, the #reach/router will give you a smoother workaround.
In App.js, I have a button that if you click, should redirect users using React-Route to another URL, /landingpagehahaha, and should render a component called LandingPage. However, neither the URL is being changed in my browser nor the correct component being rendered. The behavior right now when you click the button is that the current page gets re-rendered, not the correct LandingPage component.
The React-Route logic is placed in a function called routeChange(). I put 2 alert() statements in it which get called, telling me that it is getting inside that function. However, nothing else changes.
I have tried using this.props.history.push("./LandingPage"); in routeChange() but it doesn't get past that statement. It appears like it behaves like response.json(), which returns from the function after it runs.
I have also tried using withRouter(), but I get a weird error that I can't call Route inside Router. I was unable to resolve that issue.
// Changes route
routeChange() {
alert("HELLO BEFORE");
alert("HELLo");
return (
<div>
<Route path="/landingpagehahaha" component={LandingPage} />;
</div>
);
}
// The button that is supposed to bring user to next page
<button onClick={this.routeChange}>Go To Next Page</button>
You need to return the Redirect component from your render function, or as use the history api to push the route into your navigation stack.
The first thing you should do, is move out the route declaration, and play it higher up in your component hierachy, you have to make sure the route declaration is rendered, when you're trying to go to the route.
Instead of using the history api, you could also use the Redirect component provided by react-router. I've made a small example here.
https://codesandbox.io/s/bold-paper-kxcri
I have recently been transitioning a project from AngularJS + UI-Router+ UI-Router-Extras to React + React-Router.
One of the better features in UI-Router-Extras that I'd like to bring to React-Router is called
Deep State Redirect. In this feature, when navigating to a route which has subroutes, the application knows to redirect the user to the last subroute of it that was visited, or if none of its subroutes have yet been visited then it redirects to its first subroute to have been registered.
So for example if the loaded routing tree looks like this:
/main
|_/main_sub_1
|_/main_sub_2
/secondary
and the user starts at route /main/main_sub_2, then goes to /secondary, then goes to /main, they will be automatically redirected to /main/main_sub_2 since /main/main_sub_2 is the last subroute of /main to have been visited.
I know that I could implement this in react router by using
<IndexRedirect to={getLastSubRoute(parentRoute)}> where parentRoute is the full path of the parent <Route> tag, and getLastSubRoute is self-explanitory, but the problem with this is that I would need to add such an <IndexRedirect> tag to every single route I create, which is not optimal since the routes are loaded dynamically, there may be up to 100 subroutes, and much of the application's routing will be written by other people who I shouldn't be relying on to remember to add that tag under every <Route> tag they write.
Ideally, I should be able to apply some function or mixin to the base <Router> tag in the React routing definition to add this functionality to all routing underneath it, but I'm not sure where to start. How might I solve this problem?
Your best bet and possibly the simplest solution would be to set an onChange hook on one of the top level routes. The hook would get called with the next parameter, which would be the next route that the user would be going to.
You would also have the hierarchical structure of routes there (navigating through to parent and children of the parent), so you could dynamically redirect using the replace function, that gets passed in as a parameter also.
I implemented something similar for permission and role management. What I also did was to .bind my store to the function that I pass into the route hook. You could possibly store the route you'd like to redirect to on the user in the state tree. Basically what you refer to as getLastSubRoute.
...
<Route onChange={myRedirectFunctionThatHasStoreBound} .. >
... // other routes
</Route>
...
function myRedirectFunctionThatHasStoreBound(store, prev, next, replace, callback) {
const user = store.getState().user;
const redirectTo = getLastSubRouteForRoute(user, next);
if (redirectTo) {
replace(redirectTo);
}
// don't forget this is you list callback as a param
// your app might stop working, explanation below
callback();
}
If callback is listed as a 4th argument, this hook will run asynchronously, and the transition will block until callback is called.
EDIT: Keep in mind that this will only work if you are using react-router that's newer than or equal to in version to react-router 2.1
I can't seem to get the Backbone Router working in an expected manner. I i) instantiate my Router, then ii) call Backbone.history.start( { pushState: true, root: '/' } ). With the code below...
1) going to "/dashboard" or "/grid", the defined functions are not called
2) when I invoke myrouter.navigate("grid"), the defined functions are not called
**) However, if I then go back or forwards throught the history, then the defined functions are called.
Router : Backbone.Router.extend
routes:
"dashboard": "dashboard"
"grid/:storyid": "grid"
dashboard: ->
console.log("...")
grid: (storyid) ->
console.log("...")
What do I need to do to get cases 1) and 2) to work?
Thanks
Your router is working exactly as it's supposed to. I think your expectations of how it works, and why, are off.
1) going to "/dashboard" or "/grid", the defined functions are not called
When you type "/dashboard" or "/grid" in to your browser's URL bar, your browser makes a request to your server to get that url. This bypasses the router because the browser is making the request back to the server.
The only time typing a URL in to the browser's URL input would not request a new page from the server, is when you are only modifying the hash fragment: "#whatever".
when I invoke myrouter.navigate("grid"), the defined functions are not called
The default behavior of router.navigate is to update the URL w/ the appropriate route, but not that route to be handled by the router - exactly what you are describing.
If you want to force the browser to process the route change, pass true as a second argument: myrouter.navigate("grid", true)
**) However, if I then go back or forwards throught the history, then the defined functions are called.
This works because the router has registered itself w/ the browsers history API and is given the opportunity to handle the URL changes that are caused by the fwd / back buttons, before the browser goes back to the server to get the requested URL.