menu
announcement

Spectrum is now read-only. Learn more about the decision in our official announcement.

Gatsby

Fast in every way that matters. Gatsby is a free and open source framework based on React that helps developers build blazing fast websites and apps.

Channels
Team

Pass information between two forms

April 30, 2021 at 3:29pm

Pass information between two forms

April 30, 2021 at 3:29pm

Concept

I have two forms. When the user submit the first form(MyForm.js) I want to redirect the user to the second form(ChooseFrom.js). Both of the form are in two different pages. First form(MyForm.js) has First Name, Last Name, Total Price and Email inside it. And all of these variables will be passed to second form(ChooseFrom.js) after the first form(MyForm.js) is submitted.

Things I want to do

  • Navigate to the second form page after the first form is submitted.
  • Pass First Name, Last Name, Total Price and Email from First Form to Second Form.

Things I've already tried

Already tried using Props but no luck. I also tried using navigate("/ChooseForm/", {state: data}) from Gatsby Link API but can't pass the info as the first form is divided into three pieces.

Live sandbox

I don't have much knowledge about React. I'm still learning.😅 So, any help will be really appreciated.

April 30, 2021 at 11:42pm
I'm not sure how active this forum is anymore. There is a discord channel for general help, as well as the discussions forum on the Gatsby github repository. I think I can answer your question, however.
The reason passing data between pages in Gatsby gets a little tricky is because the routing is handled higher in the tree than you have access to in /src/pages. This is why you have to use wrapPageElement and wrapRootElement inside of gatsby-ssr and gatsby-browser (see Gatsby Browser APIs and Gatsby SSR APIs
A good method is to keep some kind of (semi-)global state, which can do with React Context, Redux, or other kinds of state management. You would place the Provider component in wrapRootElement, and then consume it in each of the pages. You could use browser history state (second parameter in the navigate() function, or by using the <Link> element: ref); you just need to remember to hydrate your new form on the other page from the location.state prop; also keep in mind that there is a capacity limit on history.state
I took the liberty of forking your codesandbox and getting it working. You can find it here. A few notes on what I did:
  • Take note of /src/root.jsx, /src/context.jsx, and /gatsby-browser.js//gatsby-ssr.js
    • You'll notice that I created global state to store my "domain state"; in this case, the information the user is entering throughout the app. This may not always be the most desirable... you may want this state to be more localized, and there are ways to do that. This is just one method.
  • You'll also notice that I used a utility function for updating the state. I was always doing a merge of the state values, so I made a function that would do it one place and passed that down through context. You could also organize the state into logical categories, like:
state = {
shoppingCart: {
...
}
}
Then use utility functions that know how to update that particular chunk of the global state
  • I consume the global app state inside of ChooseForm, telling the FieldInput components to use the global state values as the default
  • I didn't see firstName or lastName filled in anywhere except on the second form, so it appears as though that's where they should be defined. They will wind up being empty values in global state until that step is submitted, but if you were to navigate back to that page later (without a full refresh), they would have kept the values
A few general notes on the project:
  • I had to add bootstrap as a dependency then add the necessary css to gatsby-browser.js in order to get reactstrap working
  • It is not a good idea to store components inside of the pages directory. Things like ChooseForm and index are good, because those are actual routes. Everything else is a component: MyForm, steps, fields... these are not pages, and that is one reason Gatsby is printing a bunch of warnings when you build.
    • I've moved the other modules into places that seemed to make sense, but obviously their placement is up to you
  • You don't even necessarily need ChooseForm to be a new route, but perhaps it was your intention for it to be a separate page. Maybe something like a "Checkout" page?
Edited

May 2, 2021 at 4:59pm
Thanks a lot (js-brecht) for all the effort you took to help me. Thanks for the fork. It is working flawlessly. This would have been completely impossible without you because it took me a long to even understand the changes you made😅. Thanks for the long explanation, it really helped to clear up some confusions. There is supposed to be firstname and lastname in the first form but I forgot to add that...sorry😅. Thanks again.