In my React app, I've used import Router from 'next/router' to move to another page with: Router.push('/form').
However on form where I have the function component:
export default function FormOnSubmitExample() { ... }
I want to be able to pass some props into it (these have already been gathered on the first page/from where I'm directing from.
How is this possible?
Thanks.
Related
i'm still new to nextjs and i'm building static site, i'm trying to make server responsible for rendering navigation links but i can't figure this yet how to do this and how to fetch those links
as you know navigation links lies in seperate component and not included in every page and also fetching data must be in nextPage not in the components
the only solution i have is to fetch navigation links when home page loads and then get the navigation links as props and pass it the context but this will make the client responsible for rendering the naviagtion
my _app.js is
import '../styles/globals.scss'
import { Layout } from '../components'
function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
export default MyApp
as you see the Layout contains the navigation and Component has the rest
The global data should come from the layout, not from the page. If you have more than one page, you don't want to repeat your API calls in each pages.
If you use the nextjs 13 (still in beta atm), you can do this in the app/ directory. If you don't, you will need to use useSwr in your layout : https://nextjs.org/docs/basic-features/layouts.
To summarize, if you really want to be client agnostic on this feature, i think you need to try nextjs 13.
Code Sandbox link:
and trying to follow this article
On successful login(/auth/login), the user should be routed to the dashboard(/admin/summary). If the login is successful, I am also storing an access token.
I have a PrivateRoute component for this. The problem is that on successful login, the URL is getting updated but the component is not getting rendered.
PS: about the dashboard, this is a single page application so, the dashboard has topbar, sidebar, and the right content and altogether these things are coupled inside <AdminLayout/>. So, in my AppRouter, I have to render the <AdminLayout/> and just any one component.
All the react and redux code is included in the code sandbox.
Since in your code you create your own history object (it happens in you history.js file, when you call createBrowserHistory()) but doesn't pass it to your Router, nothing happens.
There are 2 possible solutions:
1. Don't create a history object yourself, but use useHistory hook inside your component
Working Demo
With this approach, you should remove history.push from login.actions.js (which imports history) and use history.push in Login.js (which uses useHistory hook):
// login.actions.js
...
loginService.login(userid, password, rememberPassword).then(
(userid) => {
dispatch(success(userid, password, rememberPassword));
// history.push(from); <-- commented out!
},
(error) => { ... }
);
};
...
// Login.js
function handleSubmit(e) {
...
const { from } = {
from: { pathname: "/admin/summary" }
};
history.push(from) // <-- added!
dispatch(loginActions.login(inputs, from));
...
}
useHistory exposes the history object of BrowserRouter (I think this is implied in this official blog post).
2. Create a history object yourself, but pass it to a Router component
Working Demo
This approach would require you to make several changes:
Creating the history object on your own means you become responsible to provide it to a router component, but it can't be a BrowserRouter, but the base Router component (see these Github answers: 1, 2).
Once you import Router (instead of BrowserRouter), you need to get rid of any useLocation and useHistory imports, otherwise you'll get errors.
I also had to unify the history object export and imports, so that it is exported as the default export (i.e., export default history), and it is imported as the default import (i.e., import history from "./history"; instead of import { history } from "./history")
(P.S: this approach can be seen implemented elsewhere on SO, for example here or here (the latter explicitly installs history, but it's not needed in your case).
I am new using react router v4. I have a link that runs a function in the onClick event and then redirects to a specific route.
This is the link:
<Link className={''}
to={'/test'}
onClick={this.testFunction}>To test</Link>
and the test function:
testFunction(event){
e.preventDefault();
// do some things...
this.props.history.push('/test');
}
This works but I need to write both times the "/test" route (in the Link component and in the function).
Is there a way of getting the "to" prop so I don't have to write it twice?
If you use "withRouter" in your component:
import {Link, withRouter} from 'react-router-dom';
...
export default withRouter(TestComponent);
you can access the route's path by using:
this.props.match.path
Use this in your code:
testFunction(event){
e.preventDefault();
// do some things...
this.props.history.push(this.props.match.path);
}
When you use "withRouter" in your component you can access the match, location and history props of the route.
withRouter official documentation
match official documentation
Hope it helps!
In an application using react, redux and react-router, I'm using react-router-redux to issue navigation actions. I found that wrapping routes in a component with connect blocks navigation.
I made a sample with CodeSandbox that illustrates the issue: sample.
As is, the navigation doesn't work. However, if in ./components/Routes.jsx, this line:
export default connect(() => ({}), () => ({}))(Routes);
Is replaced by:
export default Routes;
It works.
Any idea how I could use connect in a component that wraps routes without breaking navigation?
See the troubleshooting section in react-redux docs.
If you change Routes.jsx export to:
export default connect(() => ({}), () => ({}), null, { pure: false })(Routes);
it will work.
This is because connect() implements shouldComponentUpdate by default,
assuming that your component will produce the same results given the
same props and state.
route changes, but props don't so the view doesn't update.
You could achieve same with withRouter hoc.
Not meant to be a duplicate.
I fixed it with withRouter like this
import { withRouter } from 'react-router-dom';
and
export default withRouter( connect(mapStateToProps)(App) );
See Redux, Router integration docs here
Have you ever encountered the warning message:
Warning: You cannot change <Router history>
Well use withRouter from react-router-dom
I have searched for this for so long because the Redux was recreating my App.jsx component which has <Route> </Route> as parents and this warning just freezes the routing in my app. I wanted to have React/Redux component, because I needed to pass authenticated props to the Route component, and redirect base on it, simple.
So import { withRouter } from 'react-router-dom'
and surround your component which is connected to redux with:
export default withRouter(connect(mapStateToProps)(App));
Something more:
Most of the times if you want to communicate with the router, takes some props, pass something else to it, get history, locations form it and you are using Redux in your app, surround this component with withRouter and you will have access to these properties as props.
First things first is this possible to have 2 components on a page one displaying simple static markup but the second one in my parent is going to be a div that displays a link for each item in an array and if you click on it at the bottom of the div then data will be displayed for each one?
If this is possible are dynamic props as simple as performing .map inside the element and printing out a route?
Will also add that I am receiving the following on my Router object but I installed react-router globally though it is also in my node_modules folder.
'react-router' does not contain an export named 'hashHistory'.
import React, { Component } from 'react';
import { Router, Route, IndexRoute, hashHistory } from "react-router";
class DetailsComponent extends Component {
render() {
return (
<Router history={hashHistory}>
// in here will map this.props.data and for each one print a route
// the component for that route will be a DetailedViewComponent that
// that takes in the data in the props and renders it
// so i might need a link? in this render method aswell?
</Router>
);
}
}
export default DetailsComponent ;
React Router match params can be used to render content dynamically
ie. <Route path="/dynamicroute/:id" component={DynamicComponent}/> will provide an id param that can be retrieved via props.match.params inside <DynamicComponent/>
Spoke to some more senior react developers and they said what I was after was npm package Component-Router I haven't got back onto the project just yet but will post full code once completed :)