Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
In this article, we will make a Subreddit feed App in React JS. We will have an application where we will get a Subreddit feed list from specific Subreddit. This app will fetch all the post lists along with the header, as new posts will be added so that post also will be visible 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, here we have imported the useState hook and also the Article component where we will do something later. Now in the App function, we have added article and subreddit states with some default value, then in the return statement we have added a header tag where we have an input field in which the value will be stated. And also if we change the value of input then we will set the 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 the useEffect hook so that we can get results before the application gets loaded. Here we used the fetch method to get a result from Reddit, we used a URL and the username will be dynamic due to the usage of state. Then we will fetch the results in the form of. JSON format, after that, we will manage exceptions in case any error occurs. Also, we will get all the data till the data is empty, and we just put that data into the 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 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 the map() method to fetch every feed available from the fetch method. We will add an Article component for each data element, here we will pass article.data as a prop to the Article.js component so that every feed has an 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, and now we will add a 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 to 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 the Awesome Reference video here:
You may Also like: