News List
After setting up the project. We can start building our website using ReactSDK features. Let's start with building the home page of Hacker News.
1. Create some news
If you are using ReactSDK Tutorial community, there already exist some news. But if you started with your community, create some posts in the default space of your community (typically named "General").
2. Create NewsList Component
Create a new component named NewsList
and route /
to it in App.tsx
.
import React from 'react';
import {Routes, Route} from "react-router-dom";
import NewsList from "./components/NewsList";
function App() {
return (
<Routes>
<Route path="/" element={<NewsList/>}/>
</Routes>
);
}
export default App;
Now we easily use the useFeed
hook to retrieve the data from the community and show it in out website.
import React from 'react';
import {simplifyPaginatedResult} from "@tribeplatform/react-sdk/utils";
import {Post} from "@tribeplatform/gql-client/types";
import {useFeed} from "@tribeplatform/react-sdk/hooks";
function NewsList() {
const {data} = useFeed({
fields: {
createdBy: {
member: 'basic'
}
},
variables: {
limit: 10,
}
})
const {nodes: posts} = simplifyPaginatedResult<Post>(data)
return (
<div className="lg:w-3/4 m-auto flex flex-col">
{posts.map((post, i) => (
<div className="flex gap-2 bg-hacker-body p-2" key={post?.id}>
<div className="flex flex-col justify-center">
{i + 1}.
</div>
<div className="flex flex-col flex-grow">
<div>
{post.title}
</div>
<div className="flex gap-2 text-xs text-gray-500">
<div>
By {post.createdBy?.member?.name}
</div>
|
<div>
{post.reactionsCount} upvotes
</div>
|
<div>
{post.repliesCount} comments
</div>
</div>
</div>
</div>
))}
</div>
);
}
export default NewsList;
The data retrieved from useFeed
is paginated we use simplifyPaginatedResult
to flatten them in to an array.
The data retrieved from useFeed
does not include the
post.createdBy
by default we have to explicitly specify it in the fields
.
Now your website will show the titles of the news.
3. Add infinite scroll
Install react infinite scroller. Unfortunately, the package
does not come with typings, so we have to do a little trick to ignore the types. Add typings.d.ts
to the src
folder.
declare module "react-infinite-scroller" {
export default any;
}
Then we can use fetchNextPage
and hasNextPage
property of useFeed
to easily create an infinite scroll.
import React from 'react';
import {simplifyPaginatedResult} from "@tribeplatform/react-sdk/utils";
import {Post} from "@tribeplatform/gql-client/types";
import {useFeed} from "@tribeplatform/react-sdk/hooks";
import InfiniteScroll from 'react-infinite-scroller';
function NewsList() {
const {
data,
fetchNextPage,
hasNextPage,
} = useFeed({
fields: {
createdBy: {
member: 'basic'
}
},
variables: {
limit: 10,
}
})
const {nodes: posts} = simplifyPaginatedResult<Post>(data)
return (
<div className="lg:w-3/4 m-auto flex flex-col">
<InfiniteScroll
pageStart={0}
loadMore={fetchNextPage}
hasMore={hasNextPage}
>
{posts.map((post, i) => (
<div className="flex gap-2 bg-hacker-body p-2" key={post?.id}>
<div className="flex flex-col justify-center">
{i + 1}.
</div>
<div className="flex flex-col flex-grow">
<div>
{post.title}
</div>
<div className="flex gap-2 text-xs text-gray-500">
<div>
By {post.createdBy?.member?.name}
</div>
|
<div>
{post.reactionsCount} upvotes
</div>
|
<div>
{post.repliesCount} comments
</div>
</div>
</div>
</div>
))}
</InfiniteScroll>
</div>
);
}
export default NewsList;
You can see the final result here.