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;