Post Component in React

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;

Leave a Reply

Your email address will not be published. Required fields are marked *