How to always fetch fresh data when change route using link component in nextjs 13?

121 views Asked by At

I am using nextjs 13 app directory along with its server components. When I change routes in nextjs, I suppose to change the data in my app because it should fetch newer data every time when route changes. But it does not happen.

I used

import PostCard from "@/components/posts/PostCard"
import PostSearch from "@/components/posts/PostSearch";
import TopUsers from "@/components/users/TopUsers";
import { getPosts } from "@/requests/posts";

async function fetchAllPosts(title, tags) {
    try {
        const allPosts = await getPosts();

        if (!title && !tags) {
            return allPosts;
        }
        else if (title && tags) {
            const posts = [];
            let isMatched = false;
            allPosts.map((post) => {
                const postTitle = post.title.toLowerCase();
                const postTags = post.tags;
                tags.split(' ').map((tag) => {
                    if (postTags.includes(tag)) isMatched = true;
                });
                if (postTitle.includes(title.toLowerCase()) || isMatched) {
                    posts.push(post);
                }
            });
            return posts;
        }
        else if (title) {
            const posts = [];
            allPosts.map((post) => {
                const postTitle = post.title.toLowerCase();
                if (postTitle.includes(title.toLowerCase())) {
                    posts.push(post);
                }
            });
            return posts;
        }
        else if (tags) {
            const posts = [];
            let isMatched = false;
            allPosts.map((post) => {
                const postTags = post.tags;
                tags.split(' ').map((tag) => {
                    if (postTags.includes(tag)) isMatched = true;
                });

                if (isMatched) {
                    posts.push(post);
                }
            });
            return posts;
        }


    } catch (error) {
        console.log(error);
    }
}

export const dynamic = 'force-dynamic';

export const metadata = {
    title: 'Posts - CodeStacks',
    description: 'Find out best of CodeStacks programming and coding related posts here.',
}

const page = async ({ searchParams }) => {
    const searchTitle = searchParams.title || null;
    const searchTags = searchParams.tags || null;

    const posts = await fetchAllPosts(searchTitle, searchTags);

    if ((posts?.length === 0) && !searchTitle && !searchTags) {
        return (<div className="w-full flex justify-center py-10">
            <span className="text-foreground/80 text-base">No posts found. Try to wait for users to post...</span>
        </div>)
    }

    return (
        <div className="flex">

            {/* Posts Section */}
            <div className="px-10 w-3/5 max-xl:w-2/3 max-lg:w-full max-md:px-3">
                <PostSearch searchTitle={searchTitle} searchTags={searchTags} />
                <ResultsText searchTitle={searchTitle} searchTags={searchTags} posts={posts} />
                <div className="py-10 px-10 flex flex-col justify-center space-y-5 max-lg:items-center max-xl:px-5 max-lg:px-20 max-md:px-0">

                    {
                        posts?.reverse().map(async (post) => {
                            return <PostCard key={post._id} id={post._id} name={post.user.name} username={post.user.username} image={post.user.image} devlab={post.user.devlab || "Not in Dev Lab"} time={post.createdAt} title={post.title} tags={post.tags} views={post.views} likes={post.likes} />
                        })
                    }
                </div>
            </div>

            <div className="max-lg:hidden w-1/4 flex flex-col items-end">
                <TopUsers />
                <div>
                    Top Devlabs
                </div>
            </div>

        </div>
    )
}

const ResultsText = ({ searchTitle, searchTags, posts }) => {

    if ((posts?.length === 0) && (searchTitle || searchTags)) {
        return (<div className="w-full flex justify-center py-10">
            <span className="text-foreground/80 text-base">No posts found with the given title or tags.</span>
        </div>)
    }

    if (searchTitle && searchTags) {
        return (<div className="w-full flex flex-col pt-10">
            <span className="text-foreground text-lg">Showing Search Results</span>
            <div>
                <span className="font-medium text-base">Title :</span>
                <span className="pl-1 font-semibold text-muted-foreground">{searchTitle}</span>
            </div>
            <div>
                <span className="font-medium text-base">Tags :</span>
                <span className="pl-1 font-semibold text-muted-foreground">{searchTags.split('+').map((tag) => { return tag })}</span>
            </div>
        </div>)
    }

    else if (searchTitle) {
        return (<div className="w-full flex flex-col pt-10">
            <span className="text-foreground text-lg">Showing Search Results</span>
            <div>
                <span className="font-medium text-base">Title :</span>
                <span className="pl-1 text-muted-foreground font-semibold">{searchTitle}</span>
            </div>
        </div>)
    }
    else if (searchTags) {
        return (<div className="w-full flex flex-col pt-10">
            <span className="text-foreground text-lg">Showing Search Results</span>
            <div>
                <span className="font-medium text-base">Tags :</span>
                <span className="pl-1 text-muted-foreground font-semibold">{searchTags.split('+').map((tag) => { return tag })}</span>
            </div>
        </div>)
    }
}

export default page

But I have to refresh page to see newer data? Is it possible that nextjs fetch latest data I mean posts from database even when I use Link component to change route?

1

There are 1 answers

0
alpha_N1618 On

Just remove the try-catch block it will solve your error.
Also make a whole reusable component for the api call.