Week 10, Day 1
This class period will be Topic I - Part 2 for Nov 3 in your instructor’s
Agenda.md.*Instructor Note: Zoom to 125% and F11 for FullScreen.
We’re going to take a look at how to “rehydrate” data in the client by changing routes and using the NextJS getServerSideProps() to reload the data on the backend.
Lesson Prep
Section titled “Lesson Prep”In the steps for this demo, we will be editing the <Home> component from the pages/index.js. There will be several edits, which we will perform in discrete steps.
Because of the amount of code in this file, take a few moments to see where everything is, so that you can locate where in the entire file you will need to make changes in each step.
When following along in class, be sure to commit after each step; use the bold text from the step description as your commit message.
Begin Editing…
Section titled “Begin Editing…”-
Define Server-Side processing
pages/index.js // ...keep code above ⬆️import { getReviews, postReview } from '../utils/api/reviews.js'export async function getServerSideProps(context) {const reviews = await getReviews();// equivalent to .then() in promises, the syntax is just a bit different.return {props: {reviews: reviews}, // will be passed to the page component as props};}export default function Home() {export default function Home(props) {console.log("Home Props:", props); // Comment out when you are sure// ...keep code below ⬇️You should see the data in the Browser Dev Tools’ Console.
-
Switch to props for data instead of state
pages/index.js // ...keep code above ⬆️<Boxsx={{pt: 2,pb: 2,}}>{reviews.map((adaptation, index)=> {{props.reviews.map((adaptation, index)=> {return <AdaptationReviewCardkey={index}id={adaptation.id}deleteCallback={deleteReviewItem}rating={adaptation.rating}title={adaptation.title}comment={adaptation.comment}/>})}</Box>// ...keep code below ⬇️Confirm that it is rendering correctly. You may need to refresh (Ctrl F5) your page.
-
Clean up unused reliance on effect
Either delete or comment out the lines of code indicated below.
pages/index.js // ...keep code above ⬆️// on the client side, our function will fetch// all of our reviews on loading of the page.useEffect(()=> {loadAllReviews()}, [])// for debugging "reviews" purposes onlyuseEffect(()=> {console.log(reviews)}, [reviews])// ...keep code below ⬇️pages/index.js // ...keep code above ⬆️const loadAllReviews = () => {getReviews().then((data)=> {setReviews(data)})}// ...keep code below ⬇️ -
Setup the router for refreshing data
pages/index.js // ...keep code above ⬆️import { useRouter } from 'next/router';import { getReviews, postReview } from '../utils/api/reviews.js'// ...keep code below ⬇️pages/index.js // ...keep code above ⬆️export default function Home(props) {// console.log("Home Props:", props); // Comment out when you are sureconst router = useRouter();const refreshData = () => {router.replace(router.asPath);}// ...keep code below ⬇️Changing the route will be our way to trigger interaction with the server, and thus refreshing our data.
-
Trigger router on adding/deleting reviews
pages/index.js // ...keep code above ⬆️const deleteReviewItem = (deleteReviewId) => {let allReviews = reviews.filter((review)=> {return review.id !== deleteReviewId})setReviews(allReviews)refreshData();}// ...keep code below ⬇️pages/index.js // ...keep code above ⬆️const handleSubmit = (event) => {event.preventDefault()postReview({title,comment: comments,rating}).then((data)=> {setReviews([data, ...reviews])refreshData();})}// ...keep code below ⬇️ -
Remove unused state variables
pages/index.js // ...keep code above ⬆️const [reviews, setReviews] = useState([])const [title, setTitle] = useState("")const [comments, setComments] = useState("")const [rating, setRating] = useState(0)// ...keep code below ⬇️The only remaining state variables are those that involve our form inputs.
Conclusion
Section titled “Conclusion”With this example, we leveraged server-side processing () and routing () to keep some of the component’s “state awareness” separate from the primary focus of the component, which is rendering a list of reviews and facilitating the adding and removing of reviews.
In other words, we removed having to manage the persisted state (all the reviews on the back end) from our client-side code. Persistence is all handled in the back end. By use of “route-refreshing” and Server-Side Props, we’ve handling all that processing on the server.
Note: This is not a perfect fit for all components and situations, but it does have its use cases.