Wasif Khalil
Wasif Khalil

Reputation: 2247

Next.js keep the state or send props when router.push

I'm new to Next.js and I am redirecting the user to next page using router.push

router.push("/terminal_summary");

My Redux state is empty on the next page, but I need the data I have in the state. How do I keep it or at least how can I send some props with router.state?

I tried router.push("/terminal_summary", undefined, { shallow: true }); but it doesn't work.

I have also tried:

router.push({
  pathname: '/terminal_summary',
  query: props.terminalPayload
})

But it sends data in query parameter.

The best thing would be to keep all the data in state or at least I want to be able to redirect with props.

EDIT:

On the next page I'm trying to access the Redux state using mapStateToProps

function mapStateToProps(state) {
  return {
    terminalPayload: state.terminalPayload,
  };
}

But this state after redirecting is showing initialState instead of the changes I have done on the previous page.

So the value is {} but it is supposed to be an object like below.

{
   merchant: [{ /*multiple objects*/ }],
   products: [{ /* multiple products*/}],
   // other data
}

Please note, this is currently not saved in the db and supposed to be saved on the next page where I want to show the summary then ask user to save.

Another note, I can see the data from Redux DevTools in Chrome but when I access on the page it is {}.

EDIT 2:

here is the complete redux code:

configureStore.js

export default (initialState) => {
  return createStore(
    rootReducer,
    initialState,
    composeWithDevTools(applyMiddleware(thunk, reduxImmutableStateInvariant()))
  );
};

reducers/index.js

const rootReducer = combineReducers({
  terminals,
  merchants,
  distributors,
  terminalPayload,
  roles,
  /* other reducers */
});

export default rootReducer;

initialState.js

export default {
  terminals: {
    imported: [],
  },
  merchants: [],
  distributors: [],
  terminalPayload: {},
  roles: [],
};

I'm using next.js so i have _app.js file where i have this code:

import configureStore from "../redux/configureStore";

function MyApp({ Component, pageProps }) {
  let state = {};
  const store = configureStore();

  return (
    <Provider store={store}>
      <Layout>
        <Component {...state} />
      </Layout>
    </Provider>
  );
}

then i have some actions and where is how i subscribe to it

terminal.js

const terminal = (props) => {
     const router = useRouter();
     /* functions */
     /* i have a function here that use router.push('terminal_summary') to redirect user to next page */
     return /* jsx */
}

function mapStateToProps(state) {
  return {
    terminals: state.terminals,
    terminalPayload: state.terminalPayload,
  };
}

function mapDispatchToProps(dispatch) {
  return {
    terminalActions: bindActionCreators(terminalActions, dispatch)
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(terminal);

terminal_summary.js

const terminalSummary = (props) => {
  const router = useRouter();


  return (
    /* jsx */
  );
};

terminalSummary.propTypes = {
  terminalPayload: PropTypes.object.isRequired,
};

function mapStateToProps(state) {
  return {
    terminalPayload: state.terminalPayload, // this object is empty here {} which is supposed to be same as i had on terminal.js page
  };
}

function mapDispatchToProps(dispatch) {
  return {};
}

export default connect(mapStateToProps, mapDispatchToProps)(terminalSummary);

i have been looking into this and im not sure if it is something related to this:

https://nextjs.org/docs/api-reference/data-fetching/getInitialProps https://github.com/kirill-konshin/next-redux-wrapper

Upvotes: 11

Views: 20140

Answers (1)

Drew Reese
Drew Reese

Reputation: 203466

Nextjs doesn't really allow for route state like many other common client-side routing/navigation libraries, but you can send data via the query parameter and then "hide" them from the address bar using the as parameter of router.push.

Next.js 14

Page Router

useRouter - This appears to function the same as v13 and below.

Use the as option, same as older versions, e.g. router.push(url, as, options)

import { useRouter } from 'next/router';

...

router.push(
  {
    pathname: '/terminal_summary',
    query: props.terminalPayload
  },
  '/terminal_summary',
);

Reciever

import { useRouter } from 'next/router';

...

const router = useRouter();
const terminalPayload = router.query; // <-- terminalPayload sent in query parameter

App Router

The app router and useRouter hook do not have this functionality. Any data passed will be included with the URL path in the queryString.

useRouter: router.push(href: string, { scroll: boolean })

import { useRouter } from 'next/navigation';

...

router.push(`/terminal_summary?param=${terminalPayload}`);

Next.js older

as - Optional decorator for the URL that will be shown in the browser. Before Next.js 9.5.3 this was used for dynamic routes, check our previous docs to see how it worked

router.push(
  {
    pathname: '/terminal_summary',
    query: props.terminalPayload
  },
  '/terminal_summary',
);

On the receiving route access the query object.

const router = useRouter();
const terminalPayload = router.query; // <-- terminalPayload sent in query parameter

Upvotes: 9

Related Questions