Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
In this article, we will make Subreddit feed App in React JS. Basically, we will have an application where we will get Subreddit feed list from specific Subreddit. This app will fetch all the post list along with header, also as new post will be added so that post also will be visible in here, so it will be dynamic.
Here, we are going to use Reddit’s API to fetch the posts list of any particular Subreddit. This will be very easy to make, so let’s build this step-by-step.
Okay, let’s move to our App.js component, in here we have imported useState hook and also Article component where we will do something later. Now in App function, we have added article and subreddit states with some default value, then in return statement we have added a header tag where we have an input field which value will be state. And also if we change the value of input then we will set state with that value. Lastly, we have added a div for articles.
import React, { useState, useEffect } from 'react';
import Article from './components/Article';
function App() {
const [articles, setArticles] = useState([]);
const [subreddit, setSubreddit] = useState('gaming');
return (
<div className="App">
<header>
<input className="subreddit_input" onChange={e => setSubreddit(e.target.value)} value={subreddit} />
</header>
<div className="articles">
</div>
</div>
);
}
export default App;
Now let’s put a logic for fetching feed, Here we will use useEffect hook so that we can get result before application gets loaded. In here we used fetch method to get a result from Reddit, here we used a URL and username will be dynamic due to usage of state. Then we will fetch the results in form of .JSON format, after that we are managing exception in case any error occurs. Also, we will get all the data till data is not empty, and we just put that data into article state. data.data.childern
will help us to get raw data from an API.
useEffect(() => {
fetch("https://www.reddit.com/r/" + subreddit +".json").then(
res => {
if (res.status !== 200) {
console.warn("Warning: Something is wrong with the api.");
return;
}
res.json().then(data => {
if (data != null)
setArticles(data.data.children);
});
}
)
}, [subreddit]);
Now let’s move to our Article.js component, here we have created a variable where we will store a base URL which is of course “https://reddit.com”. Then we will create an article tag where we simply added an anchor tag and in here we have added a link to that particular post, for that we will add props.article.permalink
after base_url. permalink will be available from feed data which we have fetched earlier.
In App.js, we have to use map() method to fetch every feed available from fetch method. We will add Article component for each data element, here we will pass article.data as prop to Article.js component so that every feed have anchor link as per their permalink.
App.js
return (
<div className="App">
<header>
<input className="subreddit_input" onChange={e => setSubreddit(e.target.value)} value={subreddit} />
</header>
<div className="articles">
{(articles != null) ? articles.map((article, index) => <Article key={index} article={article.data} />) : ''}
</div>
</div>
);
Article.js
import React from 'react';
function Article(props) {
let base_url = 'https://reddit.com';
return (
<article>
<a href={ base_url + props.article.permalink } target="_blank">
<h3>{ props.article.title }</h3>
</a>
</article>
)
}
export default Article;
Okay, we have fetched our data successfully, now we will add little CSS in styled components. Here we added common CSS as always, which you can simply modify to get your favorite effects. So here we did not do any special it’s like common CSS, so will move on another part of the logic.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: montserrat, sans-serif;
}
header {
background-color: #FFCE00;
background-image: linear-gradient(to right, #FE4880, #FFCE00);
box-shadow: 0px 3px 6px rgba(0,0,0,0.2);
padding: 15px;
}
header .subreddit_input {
display: inline-block;
color: #F3F3F3;
font-size: 32px;
font-weight: 600;
font-style: italic;
text-transform: uppercase;
background: none;
border: none;
outline: none;
appearance: none;
}
header:before {
content: "/r/";
display: inline-block;
color: #F3F3F3;
font-size: 32px;
font-weight: 600;
font-style: italic;
text-transform: uppercase;
text-align: center;
}
.articles article {
padding: 30px 15px;
background-color: #FFF;
color: #212121;
}
.articles article a {
text-decoration: none;
}
.articles article h3 {
color: #212121;
}
.articles article:nth-child(2n) {
background-color: #F3F3F3;
}
.articles article:hover {
background-image: linear-gradient(to left, #FE4880, #FFCE00);
}
.articles article:hover h3 {
color: #FFF;
}
App.js
import React, { useState, useEffect } from 'react';
import Article from './components/Article';
function App() {
const [articles, setArticles] = useState([]);
const [subreddit, setSubreddit] = useState('gaming');
useEffect(() => {
fetch("https://www.reddit.com/r/" + subreddit +".json").then(
res => {
if (res.status !== 200) {
console.warn("Warning: Something is wrong with the api.");
return;
}
res.json().then(data => {
if (data != null)
setArticles(data.data.children);
});
}
)
}, [subreddit]);
return (
<div className="App">
<header>
<input className="subreddit_input" onChange={e => setSubreddit(e.target.value)} value={subreddit} />
</header>
<div className="articles">
{(articles != null) ? articles.map((article, index) => <Article key={index} article={article.data} />) : ''}
</div>
</div>
);
}
export default App;
index.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: montserrat, sans-serif;
}
header {
background-color: #FFCE00;
background-image: linear-gradient(to right, #FE4880, #FFCE00);
box-shadow: 0px 3px 6px rgba(0,0,0,0.2);
padding: 15px;
}
header .subreddit_input {
display: inline-block;
color: #F3F3F3;
font-size: 32px;
font-weight: 600;
font-style: italic;
text-transform: uppercase;
background: none;
border: none;
outline: none;
appearance: none;
}
header:before {
content: "/r/";
display: inline-block;
color: #F3F3F3;
font-size: 32px;
font-weight: 600;
font-style: italic;
text-transform: uppercase;
text-align: center;
}
.articles article {
padding: 30px 15px;
background-color: #FFF;
color: #212121;
}
.articles article a {
text-decoration: none;
}
.articles article h3 {
color: #212121;
}
.articles article:nth-child(2n) {
background-color: #F3F3F3;
}
.articles article:hover {
background-image: linear-gradient(to left, #FE4880, #FFCE00);
}
.articles article:hover h3 {
color: #FFF;
}
Header.js
import React from 'react';
function Header() {
return (
<header>
<input class="subreddit_input" value="gaming" />
</header>
)
}
export default Header;
Article.js
import React from 'react';
function Article(props) {
let base_url = 'https://reddit.com';
return (
<article>
<a href={ base_url + props.article.permalink } target="_blank">
<h3>{ props.article.title }</h3>
</a>
</article>
)
}
export default Article;
Check out Awesome Reference video here:
You may Also like: