WP REST APIをReactでWordPressの記事一覧を表示させるスニペット [React版]

Reactのアイキャッチ画像

以前の記事では、jQueryとWP REST APIを使って記事一覧を表示するスニペットを紹介しましたが、今回はAPIでReactを使った記事一覧の方法について解説していきます。

関連記事 WP REST APIのJavaScriptで他のWordPressの記事をJSONで出力

かかかず
かかかず

また、ReactをWordPressへ導入する方法についても解説していきます。

WordPressのカスタマイズを行いたい方や、シングルページアプリケーションの運用に興味ある方は最後までご覧ください。

実装後のサンプル

早速ですが、実装後のサンプルです。

    かかかず
    かかかず

    横型のカードで、6記事をAPIで出力しています。

    記事のコンテンツをJavaScriptでレンダリングするので、速いです。

    記事一覧を表示させるまでのざっくりとした手順

    はじめに、記事一覧を表示させるまでの手順について解説します。ざっくりとしてますが、以下の通り4つのSTEPで完了です。

    ReactをWordPressに読み込ませる

    functions.phpに、React関連のファイルを読み込ませる設定を記述します。

    JSのファイルにコードを記述

    設定したJSのファイルに、WP REST APIで出力する内容をReactを使って記述します。

    表示させたい位置にHTMLを記述

    React で描画したい箇所を決めて、 DOM コンテナを追加する為にHTMLを記述します。

    CSSをコピペ

    最後に見た目を整えるCSSをコピペして完了です。

    上記のように、STEP.1で functions.php をいじるのでバックアップをとってから行うようにしましょう。

    注意点

    この記事のスニペットは、基本コピペで実装できますが functions.php をいじります。

    functions.phpは色々なことができるファイルですが、いじるのをミスってしまうと、WordPress全体が真っ白のエラーになってしまうこともあるので、注意が必要です。

    バックアップをとってからやりましょう。

    functions.phpをいじる場合、ftpで必ずバックアップを取ってから行い、テーマ本体ではなく子テーマの方に関数をコピペするようにしましょう。

    実装の手順と具体的な方法

    手順と方法

    そんな概要を抑えつつ、ReactをWordPressに入れてみます。詳細の手順について解説していきます。

    functions.phpにReact関連のファイルを読み込ませる

    WordPressには、予めReactが同梱されています。それを使う為、functions.phpに以下のコードを記述します。

    記述する時、Reactに使うjsのファイルが  my-react.js の場合、3行目の /js/my-script.js? の部分を例えば /js/my-react.js? に書き換えて記述します。

    functions.php

    add_action('wp_enqueue_scripts', function () {
    // wp-elementを指定するとreact・react-domが入ってくる。
        wp_enqueue_script('my-script', get_theme_file_uri() . '/js/my-react.js?', ['wp-element'], '1.0.0', true);
    });

    読み込ませる方法は、以下のサイトを参考にさせていただきました。

    外部リンク WordPress 5.0内でReactだけを利用する方法

    読み込みが完了すると、<head>〜</head>の中に、以下2つのファイルが出力されていればOKです。※冒頭のパスの部分は、それぞれ異なります。

    設定完了後のHTML

    <script type='text/javascript' src='https://dubdesign.net/wp-includes/js/dist/vendor/react.min.js?ver=16.13.1' id='react-js'></script>
    <script type='text/javascript' src='https://dubdesign.net/wp-includes/js/dist/vendor/react-dom.min.js?ver=16.13.1' id='react-dom-js'></script>

    かかかず
    かかかず

    上記の2つが出力されていれば、準備はこれで完了です。

    JSのファイルにコードを書く

    STEP.1で本体に読み込ませるJSのファイルに、以下のコードをコピペします。

    書き込む時は、Minifi(圧縮)して記述した方が少しでもファイルサイズを小さくできるので、そうしましょう。

    コードを表示する

    JavaScript

    "use strict";
    
    class App extends React.Component {
      constructor() {
        super();
        this.state = {
          posts: []
        };
      }
    
      componentDidMount() {
        // Workaround for CORS issues on Codepen
        let noCorsURL = "https://dubdesign.net/"; // Endpoint you want to hit
    
        let endpoint = "posts?per_page=6&_embed"; // WP API base. Don't include the protocol.
    
        let dataURL = noCorsURL + "domain/wp-json/wp/v2/" + endpoint;
        fetch(dataURL).then(res => res.json()).then(res => {
          this.setState({
            posts: res
          });
        });
      }
    
      render() {
        let posts = this.state.posts.map(post => {
          return /*#__PURE__*/React.createElement("li", {
            key: post.id
          }, /*#__PURE__*/React.createElement("a", {
            href: post.link
          }, /*#__PURE__*/React.createElement("img", {
            src: post._embedded["wp:featuredmedia"][0].source_url
          }), /*#__PURE__*/React.createElement("div", {
            className: "card_textright"
          }, /*#__PURE__*/React.createElement("p", {
            className: "card_title",
            dangerouslySetInnerHTML: {
              __html: post.title.rendered
            }
          }), /*#__PURE__*/React.createElement("p", {
            className: "card_description",
            dangerouslySetInnerHTML: {
              __html: post.excerpt.rendered
            }
          }))));
        });
        return /*#__PURE__*/React.createElement("ul", {
          class: "wp-apicard_verticl"
        }, posts);
      }
    
    }
    
    ReactDOM.render( /*#__PURE__*/React.createElement(App, null), document.getElementById('app'));

    表示させたい位置にHTMLを記述

    React で描画したい箇所を決めて、 DOM コンテナを追加する為に以下のHTMLを記述すれば完了です。

    HTML

    <div id="app"></div>

    CSSをコピペ

    最後に見た目を整える以下のCSSをコピペして完了です。

    コードを表示する

    JavaScript

    /* WP REST */
    ul.wp-apicard_verticl {
        display: flex;
        list-style: none;
        border: none;
        padding: 0;
        flex-direction: column;
        flex-wrap: wrap;
    }
    ul.wp-apicard_verticl li {
        width: 100%;
        margin-bottom:25px;
    }
    ul.wp-apicard_verticl li a {
        display: flex;
        color: #313131;
        border-radius: 2px;
        background: #fff;
        box-shadow: 0 0 3px 0 rgb(0 0 0 / 12%), 0 2px 3px 0 rgb(0 0 0 / 22%);
        cursor: pointer;
        transition: 0.2s ease-in-out;
        padding: 5px;
    }
    ul.wp-apicard_verticl li a:hover {
        text-decoration: none;
        box-shadow: 0 15px 30px -5px rgb(0 0 0 / 15%), 0 0 5px rgb(0 0 0 / 10%);
        transform: translateY(-4px);
    }
    ul.wp-apicard_verticl li a img {
        width: 30%;
        margin-right: 3%;
        object-fit: cover;
        height: 190px;
    }
    .card_textright {
        width: 70%;
        display: flex;
        flex-direction: column;
        padding-right: 20px;
        justify-content: center;
    }
    .card_textright p {
        margin: 0;
    }
    p.card_title {
        font-size: 1.2rem;
        line-height: 1.56;
        color: #555;
        font-weight: 600;
        margin-bottom: 8px;
    }
    p.card_description {
        font-size: 0.8rem;
    }
    @media screen and (max-width: 767px) {
    /* (ここにモバイル用スタイルを記述) */
    ul.wp-apicard_verticl {
        padding-left: 2%;
        padding-right: 2%;
    }
    ul.wp-apicard_verticl li {
        margin-bottom: 20px;
    }
    ul.wp-apicard_verticl li a {
        flex-direction: column;
        padding: 0;
    }
    ul.wp-apicard_verticl li a img {
        width: 100%;
        object-fit: contain;
        height: auto;
        margin: 0;
    }
    .card_textright {
        width: 100%;
        padding: 20px 25px;
    }
    }

    補足

    記事中のJSコピペ用コードは、以下JSXをコンパイルしています。

    コードを表示する

    JSX

    class App extends React.Component {
    
      constructor() {
        super();
        this.state = {
          posts: []
        }
      }
      
    componentDidMount() {
      // Workaround for CORS issues on Codepen
      let noCorsURL = "https://dubdesign.net/"
      
      // Endpoint you want to hit
      let endpoint = "posts?per_page=6&_embed"
      
      // WP API base. Don't include the protocol.
      let dataURL = noCorsURL + "domain/wp-json/wp/v2/" + endpoint
      
      fetch(dataURL)
        .then(res => res.json())
        .then(res => {
          this.setState({
            posts: res
          })
        })
      }
      
      render() {
        
        let posts = this.state.posts.map((post) => {
          return <li key={post.id}>
            <a href={post.link}>
              <img src={post._embedded["wp:featuredmedia"][0].source_url}></img>
              <div className="card_textright">
              <p className="card_title" dangerouslySetInnerHTML={{ __html: post.title.rendered }} />
              <p className="card_description" dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} />
              </div>
            </a>
          </li>
        })
        
        return (
          <ul class="wp-apicard_verticl">
            {posts}
          </ul>
        );
      }
    }
    
    ReactDOM.render(<App />, document.getElementById('app'));

    参考サイト

    参考React日本語公式サイトReact
    カテゴリーのイラスト

    同じカテゴリの記事一覧

    ボタンの影