I'm using next.js for rebuilding an app for server side rendering. I have a button that handles a search request.
In the old app, the handler was this one:
search = (event) => {
event.preventDefault();
history.push({
pathname: '/results',
state: {
pattern: this.state.searchText,
}
});
}
In the results class, I could get the state date with this.props.location.state.pattern.
So now I'm using next.js:
import Router, { withRouter } from 'next/router'
performSearch = (event) => {
event.preventDefault();
Router.push({ pathname: '/results', state: { pattern: this.state.searchText } });
};
In the results class, I use
static async getInitialProps({req}) {
return req.params;
}
I'm not sure if I have to add this to my server.js:
server.get('/results', (req, res) => {
return app.render(req, res, '/results', req.params)
})
However, the function getInitialProps throws an error because req is undefined. Long text, short question: how to pass state or params to another page without using GET parameters?
5 Answers
In next.js you can pass query parameters like this
Router.push({
pathname: '/about',
query: { name: 'Someone' }
})
and then in your next page (here in /about page), retrieve the query via the router props, which needs to be injected to Component by using withRouter.
import { withRouter } from 'next/router'
class About extends React.Component {
// your Component implementation
// retrieve them like this
// this.props.router.query.name
}
export default withRouter(About)
If you want 'clean' urls, one way to go about it is to add onClick handler to your link and store required information in context/redux store. It easy to implement if you already have one.
<Link href='...'>
<a onClick={()=>{dispatch(....)}}>Link<a/>
<Link>
If you want your url remain clean, make a small addition to Prithwee Das's answer like below.
Router.push({
pathname: '/about',
query: { name: 'Someone' }
}, '/about');
Now you can access props in your component using props
...
const YourComponent = (props) => {
useEffect(() => {
console.log(props.router.query.name);
}, [props.router.query]);
return (
<React.Fragment>
...
</React.Fragment>
);
};
...
I don't know whether this supports SSR, but I had to do it as follows to avoid the error cannot read property 'query' of undefined.
This uses useRouter hook to get access to the url, imported as below.
import { useRouter } from 'next/router'
Assume you want to pass data {name:'Someone'} from Component A to Component B.
In Component A,
const router = useRouter();
router.push(
{ pathname: "/path_of_component_b", query: { name: "Someone" } },
"path_of_component_b"
);
In Component B,
const router = useRouter();
useEffect(() => {
alert(router.query.name); // Alerts 'Someone'
}, [router.query]);
With the latest version of NextJS we have hooks and in our case useRouter
import { useRouter } from 'next/router'
function ActiveLink({ children, href }) {
const router = useRouter()
const handleClick = (e) => {
e.preventDefault()
router.push(href)
}
return (
<a href={href} onClick={handleClick}>
{children}
</a>
)
}
export default ActiveLink
and if you want a dynamic root its as simple as putting it in the string params:
<button type="button" onClick={() => router.push('/post/abc')}>
Click me
</button>