Gatsby Default Starter

PostWidget component in React

Written on July 28, 2019

This is the fifth part of Create react app with GraphQL way of WordPress data

In this part, we will develop PostWidget component and a small edit of src/components/AppRouter.js

First, let do small tweak of AppRouter.js

  • First import milligram in AppRouter to use everywhere.
  • We will use a common component in the header area of our application. Create src/components/Header.js
  • Update state to store the title
state = {
  title: "",
  posts: []
};
  • Update query to fetch Blog title
client
      .query({
        query: gql`
          {
            generalSettings {
              title
            }
            posts {
              edges {
                node {
                  id
                  title
                  date
                  link
                  content
                  excerpt
                }
              }
            }
          }
        `
      })
      .then(result => {
        this.setState({
          posts: result.data.posts.edges,
          title: result.data.generalSettings.title
        });
      });
  • Add title props in the render method of AppRouter.
      <div className="container">
        <BrowserRouter>
          <Header title={this.state.title} />
          <Switch>
            <Route
              exact
              path="/"
              render={props => <App {...props} state={this.state.posts} />}
            />
            <Route
              path="/post/:postID"
              render={props => <Post {...props} state={this.state.posts} />}
            />
            <Route component={NotFound} />
          </Switch>
        </BrowserRouter>
      </div>

So, now AppRouter.js file will

import React from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import ApolloClient, { gql } from "apollo-boost";
import "milligram";
import Header from "./components/Header";
import App from "./components/App";
import Post from "./components/Post";
import NotFound from "./components/NotFound";

class AppRouter extends React.Component {
  state = {
    title: "",
    posts: []
  };

  componentDidMount() {
    const client = new ApolloClient({
      uri: "https://mrinalbd.com/?graphql"
    });
    client
      .query({
        query: gql`
          {
            generalSettings {
              title
            }
            posts {
              edges {
                node {
                  id
                  title
                  date
                  link
                  content
                  excerpt
                }
              }
            }
          }
        `
      })
      .then(result => {
        this.setState({
          posts: result.data.posts.edges,
          title: result.data.generalSettings.title
        });
      });
  }
  render() {
    return (
      <div className="container">
        <BrowserRouter>
          <Header title={this.state.title} />
          <Switch>
            <Route
              exact
              path="/"
              render={props => <App {...props} state={this.state.posts} />}
            />
            <Route
              path="/post/:postID"
              render={props => <Post {...props} state={this.state.posts} />}
            />
            <Route component={NotFound} />
          </Switch>
        </BrowserRouter>
      </div>
    );
  }
}

export default AppRouter

Develop Header Component
In src/components/Header.js

import React from "react";
import { Link } from "react-router-dom";

class Header extends React.Component {
  render() {
    return (
      <div>
        <Link to="/">
          <h1>{this.props.title}</h1>
        </Link>
      </div>
    );
  }
}
export default Header;

Develop PostWidget
Let’s open src/components/PostWidget.js.
First import { Link } and DomPurify

import { Link } from "react-router-dom";
import DOMPurify from "dompurify";

Then, render the title in link wrapper like this

<div>
  <Link to={`/post/${this.props.post.node.id}`}>
    <p
    dangerouslySetInnerHTML={{
    __html: DOMPurify.sanitize(this.props.post.node.title)
    }}
    />
  </Link>
</div>

So, the full code of src/components/PostWidget.js is

import React from "react";
import { Link } from "react-router-dom";
import DOMPurify from "dompurify";

class PostWidget extends React.Component {
  render() {
    return (
      <div>
        <Link to={`/post/${this.props.post.node.id}`}>
          <p
            dangerouslySetInnerHTML={{
              __html: DOMPurify.sanitize(this.props.post.node.title)
            }}
          />
        </Link>
      </div>
    );
  }
}
export default PostWidget;

At last of this, our application will be