I have two pages in a Next.js project, in the first one the user fills out a form to create a post, that info gets stored in a JSON object that has to be passed to the second page so the user can see a preview of the post and if he/she likes it, the post gets created.
The object is a little to big to be passed as query parameters (it has around 25 elements in it) but I can't find how to pass it to the second page props.
The function that gives the object it's values looks like this
async function submitHandler(event) {
event.preventDefault();
validateAndSetEmail();
validateAndSetTitle();
validateAndSetSalary();
if (isFormValidated === true) {
// this checks if the user has created another post
const finalPostData = await checkExistence(Email);
if (finalPostData["user"] === "usernot found") {
setPostData({
title: Title,
name: Name,
city: City,
email: Email,
type_index: TypeNumber,
type: Type,
region_index: regionNumber,
region: region,
category_index: categoryNumber,
category: category,
range: Range,
highlighted: highlighted,
featured: featured,
show_logo: showLogo,
show_first: showFirst,
description: Description,
price: basePrice + cardPrice,
website: Website,
logo: Logo,
application_link: applicationLink,
time_to_pin: weeksToPin,
pin: pin,
post_to_google: shareOnGoogle,
});
} else {
setPostData({
// set other values to the object
});
}
// Here I want to do something like
router.push({
pathname: "/preview/",
post: PostData,
});
}
}
The second page looks something like this:
export default function PreviewPage(props) {
const item = props.postInfo; // <= I want item to recieve the JSON object from the other page
return (
<Fragment>
<Navbar />
<div className="flex inline mt-12 ml-24">
<Card
category={item.category}
Name={item.company}
logo={item.logo}
City={item.company_city}
Website={item.company_website}
/>
<Description
title={item.job_title}
description={item.description}
category={item.category}
region={item.region}
Type={item.type}
Link={item.link}
/>
</div>
<Footer />
</Fragment>
);
}
Try
router.push({
pathname: "/preview/",
query: PostData,
});
export default function PreviewPage() {
const router = useRouter()
const item = router.query
After looking into React Context and Redux thanks to knicholas's comment, I managed to find a solution.
Created a context provider file
I create the Context with 2 things inside:
An empty object representing the previewData that will be filled later
A placeholder function that will become the setter for the value
import React from "react";
const PreviewContext = React.createContext({
Previewdata: {},
setPreviewData: (data) => {},
});
export default PreviewContext;
Then in _app.js
Create a useState instance to store the previewData and have a funtion to pass to the other pages in order to set the value when the form is filled, then, wrap the component with the context provider
function MyApp({ Component, pageProps }) {
const [previewData, setPreviewData] = useState({});
return (
<div className="">
<PreviewContext.Provider value={{ previewData, setPreviewData }}>
<Component {...pageProps} />
</PreviewContext.Provider>
</div>
);
}
export default MyApp;
In the form page
I get the function to set the value of previewData by using of useContext();
const { setJobPreviewData } = useContext(jobPreviewContext);
With that the value for previewData is available everywhere in the app