Back to blogs
Blog
Writing in public
Longer posts — published here first, then cross-posted to Dev.to with a canonical URL back to this site.
Blog
Longer posts — published here first, then cross-posted to Dev.to with a canonical URL back to this site.
Back to blogs
Back to blogs
Post
Timeline and posts implementaion After changing up the backend layout and removing the replies table...
Date published

Why You Might Still Pick Next.js Over TanStack Start From a TanStack Start...

A complete theme management system for React applications with SSR support! ✨ 🌟...

A guide to creating Android home screen widgets using Expo modules, complete with state management,...
Timeline and posts implementaion
After changing up the backend layout and removing the replies table and just saving everything in the posts table with different depth levels to differentiate original posts from replies and also easily represent all the levels of nested replies
the initial request n the timeline will have null parent field and depth as 0
1http://127.0.0.1:8090/custom_posts?id=undefined&depth=0&parent=&user=v7o41qltt4ttyy&created=YYYYescape+2023-01-16T06:47:26+03:00Z
and the replies /sub replies will require a parent: the id of the post/reply t fetch replies for
1 http://127.0.0.1:8090/custom_replies?id=undefined&depth=1&parent=1o599tvtue3ghwa&user=6wdrg4lavbr&created=YYYYescape+2023-01-16T06:47:26+03:00Z2
we can now covert the routing strategy in this app is to have this little slice be responsible for all the posts , replies and sub replies
1 return createBrowserRouter([2 {3 path: '/',4 element: <RootLayout user={user} test_mode={test_mode}/>,5 // loader:userLoader(queryClient),6 errorElement: <ReactRouterError />,7 children: [8 {9 element: <TimelineLayout user={user}/>,10 children:[11 {12 index:true,13 element:<Timeline user={user}/>14 }15 ]16 },17 {18 path: '/post',19 element: <PostLayout user={user} />,20 children: [21 {22 path: ':id',23 element: <Post user={user} />,24 // loader: deferredBlogPostsLoader,25 },26 ],27 },]}28 ])
The timeline component has a list of posts and clicking on one navigates you you to the post component with it's id as the query parameter and depth and search parameter
1 {data?.pages?.map((page) => {2 return page.map((item) => {3 return (<div4 onClick={() => {5 navigate({6 pathname: 'post/' + item.post_id,7 search: createSearchParams({8 depth:(item.post_depth===""?0:item.post_depth).toString()9 }).toString()10 })}11 }12 key={item.post_id}13 className="w-[90%] md:w-[50%] p-2 flex flex-col border-black border-214 dark:border-[1px] dark:border-white rounded-lg gap-3">15 <PostsCard item={item} user={user} />16 </div>1718 )19 })
To like/comment on the post without triggering the navigate event add a stop propagation to the parent with the click event to stop the event from propagating to the parent component
1<div onClick={(event) => event.stopPropagation()}>2 ....3</div>
The Post.tsx component will fetch the posts and fetch all associated replies
the depth searchParam and id queryParam will allow us to use this component recursively and open any clicked on reply as a post
instinctively I tried using
1 navigate({2 pathname: 'post/' + item.post_id,3 search: createSearchParams({4 depth:(item.post_depth===""?0:item.post_depth).toString()5 }).toString()6 })
but in a result in a URL that looks like
1http://localhost:3000/post/0radtgd42swe3n8?depth=0/post/0radtdtdtdtn8?depth=1
so we have to hop back a route and pass in a new id into the post id param to get it to work
1 navigate({2pathname: '../' + item.post_id,3search: createSearchParams({4 depth: (item.post_depth === "" ? 0 : item.post_depth).toString()5 }).toString(),6 },7 )8
To get
1http://localhost:3000/post/0radtdtdtdtn8?depth=1
helpful resources