Top 10 Latvia-Based Software Development Companies
Learn about Latvia's top software development companies and their innovative solutions in our latest article. Discover how these tech leaders can help elevate your business.
Recently, NextJS is gaining more and more popularity as a way to build React applications. Certainly, a major contributor is the fact that NextJS offers several different data fetching strategies.
And these are:
NextJS, unlike the plain React app, offers a feature called pre-rendering. This means that pre-rendered HTML is displayed during the initial load. In traditional React applications, the entire app is loaded and rendered on the client’s side. Then, after the JS code is loaded, the application becomes interactive.
In SSG, the HTML is generated in build-time and reused for each request. After a production build is created, every request is going to reuse that statically generated HTML file.
There are also two types of static generation: with and without data.
In the first case, the HTML will be generated after fetching the data by resolving the promise. In this case, we can use the getStaticProps data fetching method… but only if you are using Next.js 9.3 or newer. If not, think about upgrading it, because the older getInitialProps method is no longer recommended and will be deprecated. This method also is called on in every client-side navigation so it’s not efficient if you don’t want to fetch data on every request.
export async function getStaticProps() {
const res = await fetch("https://jsonplaceholder.typicode.com/posts");
const posts = await res.json();
return {
props: { posts },
};
}
The really cool thing is a newly released feature called ISR (Incremental Static Regeneration), which is something between SSG and SSR. It allows you (by using a specific key called revalidate) to make the page incrementally regenerated. It means that with this key you don’t need to rebuild the app each time you want to get an update of the data fetched from the server. Just add the revalidate key with the revalidation period in seconds.
export async function getStaticProps() {
const res = await fetch("https://jsonplaceholder.typicode.com/posts");
const posts = await res.json();
return {
props: {
posts,
},
revalidate: 30,
};
}
It means that if requests come after that period, then it will fetch the data from the server again.
Another situation is when you use a dynamic page, and the path depends on some external data. In that case, we can use the getStaticPaths method telling which dynamic routes should be pre-loaded:
export async const getStaticProps = ({ params }) => {
const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${params.id}`);
const post = await res.json();
return {
props: { post },
};
}
export async function getStaticPaths() {
const res = await fetch("https://jsonplaceholder.typicode.com/posts");
const posts = await res.json();
const paths = posts.map(({ id }) => ({ params: { id: `${id}` } }));
return {
paths,
fallback: false,
};
}
There is a nice way to check which dynamic routes have been created. You can run the next build and next export and after that you will have a static version of your app in the newly created out directory.
Let`s now limit the pre-build paths:
export async function getStaticPaths() {
return {
paths: [{ params: { id: "1" } }, { params: { id: "2" } }],
fallback: false,
};
}
After running the next export, we can notice in both cases (with and without a limited number of paths) a different number of posts found in my-appoutposts.
Let’s now take a closer look at the crucial and required fallback parameter. It says what to do if the page was not pre-rendered at the build-time. If it’s set to true, the getStaticProps runs and generates that page. If false, we’ll get 404 after trying to load that specific path. Another thing: pages with fallback that are enabled in getStaticPaths cannot be exported.
Below you can find the results of trying to load the same dynamic page in both cases:
First case (without limited paths)
Second case (with limited paths and fallback set to false)
Second case (with limited paths and fallback set to true)
The main difference with SSG: new HTML is generated on every request. It’s used mostly when we are fetching some external data. In this case, there is no need to rebuild the app every time we want to update the data from the server.
export async function getServerSideProps() {
const res = await fetch("https://jsonplaceholder.typicode.com/posts");
const posts = await res.json();
return {
props: {
posts,
},
};
}
The getServerSideProps method looks very similar to getStaticProps. The difference is that getServerSideProps runs on every request, while getStaticProps runs once in build-time.
With client-side rendering, the initial load of the page is a bit slow. Communication with the server happens in the run-time. You can do it in a more traditional way:
const Blog = () => {
const [posts, setPosts] = useState([]);
useEffect(() => {
const fetchData = async () => {
const res = await fetch(
"https://jsonplaceholder.typicode.com/posts");
const posts = await res.json();
setPosts(posts);
};
fetchData();
}, []);
Also, we can use another solution, ‘swr’ – React Hooks library for data fetching by Vercel*, which is strongly recommended by NextJS creators. The SWR stands for State While Revalidate.
* Data source: SWR by Vercel
import useSWR from "swr";
const Blog = () => {
const fetcher = (url) => fetch(url).then((r) => r.json());
const { data: posts = [], error } = useSWR(
"https://jsonplaceholder.typicode.com/posts", fetcher);
if (error) return <div>Failed to load posts</div>;
if (!posts.length) return <div>loading...</div>;
return (
<>
{posts.map((post) => (
{post.title}
))}
</>
}
NextJS gives us the additional possibility of choosing which of the data fetching strategies we want to use on each page. We don’t need to follow only one solution for the whole application.
Read more:
Rails API & CORS. A dash of consciousness