I have this project where I am getting all the backend data from utils/api.js and then using getServerSideProps to retrieve it in the pages/index.js file then passing it through props to the several components that were passed to the pages/index.js. However, console-logging the data in the index.js page works fine but but console-logging the props in the components returns undefined. Pay attention to all the console.log in the index.js page, they all return data but not the one in the component in this case we will be using container/expertises.js as example
utils/api.js
import axios from "axios";
const ABOUT_API_URL = `${process.env.NEXT_PUBLIC_PYTHON_BACKEND_URL}/about/abouts/`;
const EXPERTISE_API_URL = `${process.env.NEXT_PUBLIC_PYTHON_BACKEND_URL}/expertise/expertise/`;
const PROJECTS_API_URL = `${process.env.NEXT_PUBLIC_PYTHON_BACKEND_URL}/project/projects`;
export const fetchAbouts = async () => {
try {
const response = await axios.get(ABOUT_API_URL);
return response.data;
} catch (error) {
console.error("Error fetching abouts:", error);
return null;
}
};
export const fetchExpertise = async () => {
try {
const response = await axios.get(EXPERTISE_API_URL);
return response.data;
} catch (error) {
console.error("Error fetching expertise:", error);
return [];
}
};
export const fetchProjects = async () => {
try {
const response = await axios.get(PROJECTS_API_URL);
return response.data;
} catch (error) {
console.error("Error fetching projects:", error);
return [];
}
};
pages/index.js
import { Navbar } from "@/components";
import { Expertises, Footer, Header, Testimonial, Work } from "@/container";
import Articles from "@/container/Articles/Articles";
import styles from "@/styles/homescreen.module.scss";
import { fetchAbouts, fetchExpertise, fetchProjects } from "@/utils/api";
import Head from "next/head";
export async function getServerSideProps() {
try {
const abouts = await fetchAbouts();
const expertise = await fetchExpertise();
const projects = await fetchProjects();
console.log("Fetched Abouts:", abouts);
console.log("Fetched Expertise:", expertise);
console.log("Fetched Projects:", projects);
return {
props: {
aboutsData: abouts || [],
expertiseData: expertise || [],
projectsData: projects || [],
},
};
} catch (error) {
console.error("Error fetching data:", error);
return {
props: {
aboutsData: [],
expertiseData: [],
projectsData: [],
},
};
}
}
export default function Homescreen({
aboutsData,
expertiseData,
projectsData,
}) {
console.log("expertise", expertiseData);
return (
<>
<div
className={`${styles.homescreen} flex flex-col items-center justify-center`}
>
<Navbar />
<Header />
{console.log("Passing expertiseData to Expertises:", expertiseData)}
<Expertises expertise={expertiseData} />
<Work works={projectsData} />
<Articles abouts={aboutsData} />
<Testimonial />
{/* <h2 className="head-text mt-16">Take a coffee & chat with us</h2> */}
<div className={styles.footerbg}>
<div className={styles.footerbg_div}>
<Footer />
</div>
</div>
</div>
</>
);
}
container/Expertise/Expertises.jsx
import React, { useState, useEffect, useRef } from "react";
import { motion } from "framer-motion";
import { AppWrap, MotionWrap } from "../../wrapper";
import styles from "./Expertise.module.scss";
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/css";
import "swiper/css/pagination";
import { Pagination } from "swiper/modules";
const Expertises = ({ expertise }) => {
const swiperRef = useRef(null);
console.log("container expertise", expertise);
return (
<>
<div className={styles.app__expertises}>
<Swiper
slidesPerView={"auto"}
centeredSlides={true}
spaceBetween={30}
pagination={{
clickable: true,
}}
modules={[Pagination]}
className={styles.app__skills_container}
>
{expertise?.slice(0, 6).map((exp, i) => (
<SwiperSlide key={i} className={styles.app__skills_item}>
<h3 style={{ color: exp.name.split(".")[1] }}>
{exp.name.split(".")[0]}
</h3>
<p className="text-center w-full">{exp.description}</p>
<li className={styles.list}>
{exp.img_url.map((item, index) => (
<div key={index}>
<div key={index} className={`${styles.img_div} app__flex`}>
<img src={item.url} alt={item.name} />
</div>
<p className="p-text">{item.name.split(".")[0]}</p>
</div>
))}
</li>
</SwiperSlide>
))}
</Swiper>
</div>
</>
);
};
export default MotionWrap(Expertises, "app__expertises");
The console.log in expertises returns undefined
wrapper/MotionWrap.js
import React from "react";
import {motion} from 'framer-motion'
const MotionWrap = (Component, classNamaes) => function HOC() {
return (
<div>
<motion.div
whileInView={{y: [100, 50,0], opacity: [0, 0, 1]}}
transition={{duration: 0.5}}
className={`${classNamaes} app__flex`}
>
<Component />
</motion.div>
</div>
)
}
export default MotionWrap
Just like I had guessed, the MotionWrap
HOC isn't properly forwarding the props to the wrapped component and this is why the expertise
prop was coming through as undefined
. Here is an updated adjustment to your MotionWrap HOC:
import React from "react";
import { motion } from "framer-motion";
const MotionWrap = (Component, classNames) => {
return function HOC(props) {
return (
<div>
<motion.div
whileInView={{ y: [100, 50, 0], opacity: [0, 0, 1] }}
transition={{ duration: 0.5 }}
className={`${classNames} app__flex`}
>
<Component {...props} />
</motion.div>
</div>
);
};
};
export default MotionWrap;
I believe with this adjustment, the expertise
prop should no longer come through as undefined
.