Pass information between two forms
April 30, 2021 at 3:29pmPass information between two forms
April 30, 2021 at 3:29pmConcept
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
Hello
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 APIsA 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 theFieldInput
components to use the global state values as the default - I didn't see
firstName
orlastName
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 togatsby-browser.js
in order to getreactstrap
working - It is not a good idea to store components inside of the pages directory. Things like
ChooseForm
andindex
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?
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.