Post Component in React
Written on August 01, 2019
This is the sixth part of Create react app with GraphQL way of WordPress data
In this part, we will develop a Post component for our application. But, before diving in this, we will develop a Loading component for seeing landing or search status in our application. Let’s dive into Loading component development.
Create a file named styled.js in the components directory. In this file first import styled and keyframes class from the styled-components package. Styled class is familiar to us. It helps us to style a component efficient way. Beside, the keyframes helper class will help us to develop animation. Keyframes in this package work as CSS3 @keyframes rule.
import styled, { keyframes } from "styled-components";
Then, assign styled in an exported constant named LoadingState. In this constant first, declare some general properties and in after pseudo-element define animation-name loading in special way. So, create a constant variable named loading. In this variable, we use keyframes and define animation as usual. Finally, styled.js is looked like this
import styled, { keyframes } from "styled-components";
const loading = keyframes`
from {
transform: scale(1);
}
to {
transform: scale(1.5);
}
`;
const LoadingState = styled.div`
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
position: relative;
&:after {
content: "";
position: absolute;
width: 50px;
height: 50px;
border-radius: 50%;
background-color: #dedede;
opacity: 0.4;
animation: ${loading} 1s linear 0.1s infinite alternate;
}
`;
export default LoadingState;
Now, we can import LoadingState both in App.js and Post.js. Awesome way to reuse.
Open src/components/App.js and delete styled-component import lines and related code. Just import LoadingState from styled.js file and use it second return in the render method. Now, src/components/App.js looks like this-
import React from "react";
import styled from "styled-components";
import Posts from "./Posts";
import PostWidget from "./PostWidget";
import LoadingState from "./styled";
const Widget = styled.div`
border: 1px solid gray;
padding: 10px;
p {
margin-bottom: 0;
border-top: 1px solid gray;
}
}
`;
class App extends React.Component {
render() {
if (this.props.state.length) {
return (
<div className="row">
<div className="column column-80">
{this.props.state.map(post => (
<Posts key={post.node.id} post={post} />
))}
</div>
<div className="column column-20">
<Widget>
<h3>Recent posts</h3>
{this.props.state.slice(0, 2).map(post => (
<PostWidget key={post.node.id} post={post} />
))}
</Widget>
</div>
</div>
);
}
return <LoadingState>Loading...</LoadingState>;
}
}
export default App;
Let’s dive into Post component development.
Post component development
Open src/components/post.js. First import React from react package, Dompurify from dompurify package and LoadingState from styled.js which we developed just.
import React from "react"; import DOMPurify from "dompurify"; import LoadingState from "./styled";
Then, in our Post’s render method, we have to write a little bit complex (for me) code block.
- The check component has stated in its props.
- During the checking time render LoadingState component.
- Get post ID from props match object.
- Loop every state and check this node id is equal to post id.
- If found, store this state object in a predefined variable postInfo.
- If not found, just render Post Not Found
- When post found, return post title, body in a defined format.
In code, this algorithm will be,
if (this.props.state.length) {
let postInfo = {};
const state = this.props.state;
const postID = this.props.match.params.postID;
state.forEach(function(post, index) {
if (post.node.id === postID) {
postInfo = post;
}
});
if (postInfo.node) {
return (
<div className="column">
<h2
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(postInfo.node.title)
}}
/>
<p
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(postInfo.node.content)
}}
/>
</div>
);
} else {
return <div>Post Not Found</div>;
}
}
return <LoadingState>Searching...</LoadingState>;
So, the final code of src/component/post.js
import React from "react";
import DOMPurify from "dompurify";
import LoadingState from "./styled";
class Post extends React.Component {
render() {
if (this.props.state.length) {
let postInfo = {};
const state = this.props.state;
const postID = this.props.match.params.postID;
state.forEach(function(post, index) {
if (post.node.id === postID) {
postInfo = post;
}
});
if (postInfo.node) {
return (
<div className="column">
<h2
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(postInfo.node.title)
}}
/>
<p
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(postInfo.node.content)
}}
/>
</div>
);
} else {
return <div>Post Not Found</div>;
}
}
return <LoadingState>Searching...</LoadingState>;
}
}
export default Post;