Casual Developers Note

エンジニアやデザイナー向けの技術情報・英語学習情報・海外留学情報・海外旅行情報を提供中。世界を旅して人生を楽しもう。

  • ホーム
  • 技術 Tips & Tutorials
  • 技術塾
  • ライフハック
  • 海外留学
  • 英語学習
  • コラム
  • お問い合わせ
現在の場所:ホーム / アーカイブKD

2019年4月12日 By KD コメントを書く

FormikでReactのフォームを華麗に扱う方法

FormikでReactのフォームを華麗に扱う方法

Reactのフォーム用ライブラリ「Formik」でフォームを華麗に扱う方法を紹介します。

はじめに

Reactでフォームを扱う場合、ライブラリを使わないとソースコードが煩雑になってしまいます。React/Reduxの環境でポピュラーなフォーム用のライブラリといえば「Redux Form」ですが、Redux自体は必須というわけではなく、Reactのみでフロントエンドを構築する場合もあるため、Reduxを前提としたフォーム用ライブラリを使うと、React/Reduxで構築したアプリケーションをReactのみに書き直した場合などにコンポーネントの再利用性を低下させてしまいます。そこで、Reduxとは関係のないReactのフォーム用ライブラリとして「Formik」という選択肢が出てきます。

今回は、「Formik」を使って、Reactのフォームを扱う方法を紹介します。

Formikとは?

「Formik」とは、単独で利用可能なReactのフォーム用ライブラリです。

前提

以下の準備が完了している必要があります。

  • NodeJSがインストールされていること
  • create-react-appがインストールされていること

細かいバージョンは「環境」を参照してください。

FormikでReactのフォームを作成する

ベースを作る

まずは、Reactのプロジェクトを作成し、必要なパッケージをインストールします。

$ npx create-react-app formik-sample
$ cd formik-sample/
$ rm src/App.css
$ rm src/App.test.js
$ rm src/logo.svg
$ touch src/MyForm.js
$ yarn add formik yup bootstrap reactstrap
$ tree -aI 'node_modules|.git'
.
├── .gitignore
├── README.md
├── package.json
├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
├── src
│   ├── App.js
│   ├── MyForm.js
│   ├── index.css
│   ├── index.js
│   └── serviceWorker.js
└── yarn.lock

フォームを実装する

入力チェック付きのフォームを実装しましょう。

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

serviceWorker.unregister();

index.css

body {
  text-align: center;
  font-size: 1.5rem;
  padding: 3%;
}

App.js

import React from 'react';
import MyForm from './MyForm';

const App = () => (
  <>
    <MyForm />
  </>
);

export default App;

MyForm.js

import React from 'react';
import {
Button,
Form,
FormGroup,
Label,
Input as ReactstrapInput,
FormFeedback,
} from 'reactstrap';
import { withFormik, ErrorMessage, Field } from 'formik';
import * as yup from 'yup';
const Input = ({ name, ...others }) => (
<Field
name={name}
render={({ field }) => <ReactstrapInput {...field} {...others} />}
/>
);
const ErrorFormFeedback = ({ name }) => (
<ErrorMessage
name={name}
component={({ children }) => <FormFeedback>{children}</FormFeedback>}
/>
);
const ErrorInnerMessage = ({ name }) => (
<ErrorMessage
name={name}
component={({ children }) => (
<span className="text-danger" style={{ fontSize: '1.2rem' }}>
{children}
</span>
)}
/>
);
const MyForm = ({
handleSubmit,
handleReset,
isSubmitting,
dirty,
errors,
touched,
}) => (
<div className="mx-auto col-8">
<h2>My Form</h2>
<Form className="text-left" onSubmit={handleSubmit}>
<FormGroup className="mb-2">
<Label for="myEmail">Email</Label>
<Input
type="email"
name="email"
id="myEmail"
placeholder="Enter email"
valid={dirty && !errors.email}
invalid={touched.email && !!errors.email}
/>
<ErrorFormFeedback name="email" />
</FormGroup>
<FormGroup className="mb-2">
<Label for="myUsername">Username</Label>
<Input
type="text"
name="username"
id="myUsername"
placeholder="Enter username"
valid={dirty && !errors.username}
invalid={touched.username && !!errors.username}
/>
<ErrorFormFeedback name="username" />
</FormGroup>
<FormGroup className="mb-2">
<Label for="myPassword">Password</Label>
<Input
type="password"
name="password"
id="myPassword"
placeholder="Enter password"
valid={dirty && !errors.password}
invalid={touched.password && !!errors.password}
/>
<ErrorFormFeedback name="password" />
</FormGroup>
<FormGroup className="mb-2" tag="fieldset">
<legend>Gender</legend>
<FormGroup inline check>
<Label check>
<Input type="radio" name="gender" value="male" />
male
</Label>
</FormGroup>
<FormGroup inline check>
<Label check>
<Input type="radio" name="gender" value="female" />
female
</Label>
</FormGroup>
<span className="ml-3">
<ErrorInnerMessage name="gender" />
</span>
</FormGroup>
<FormGroup check className="mb-2">
<Input type="checkbox" name="isAccepted" id="myCheck" />
<Label for="myCheck" check>
Accept
</Label>
<span className="ml-3">
<ErrorInnerMessage name="isAccepted" />
</span>
</FormGroup>
<div className="d-flex justify-content-center">
<span className="p-2">
<Button
type="button"
outline
color="secondary"
onClick={handleReset}
disabled={!dirty || isSubmitting}
>
Reset
</Button>
</span>
<span className="p-2">
<Button type="submit" outline color="primary" disabled={isSubmitting}>
Submit
</Button>
</span>
</div>
</Form>
</div>
);
const MyEnhancedForm = withFormik({
mapPropsToValues: () => ({
username: '',
email: '',
password: '',
gender: '',
isAccepted: false,
}),
handleSubmit: (values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 3000);
},
validationSchema: yup.object().shape({
email: yup
.string()
.email('Enter a correct email ')
.required('Enter an email'),
username: yup
.string()
.min(3, 'A username must contain more than 3 characters')
.required('Enter a username'),
password: yup
.string()
.min(8, 'A username must contain more than 8 characters')
.required('Enter a password'),
gender: yup
.string()
.oneOf(['male', 'female'])
.required('Check a gender'),
isAccepted: yup.boolean().oneOf([true], 'Must accept terms and conditions'),
}),
})(MyForm);
export default MyEnhancedForm;

Formikの実装方法は、Formikコンポーネントでそのままフォームを実装するシンプルな方法と、withFormikコンポーネントでフォームのコンポーネントをラップするHOC(higher-order component)の方法があります。今回は実際に使うことが多い後者のHOCの方法で実装しています。

動作確認

それでは、アプリケーションを起動し、フォームの入力チェックが正しく動くか確認しましょう。

$ yarn start

NewImage

入力チェックが正しく行われるか確認します。

NewImage

正しいデータが入力されたこを確認します。

NewImage

「Submit」ボタンをクリックして、入力したデータが表示されることを確認します。

NewImage

OKですね。

最後に

いかがでしたか?これでReduxに依存すること無く、「Formik」でReactのフォームを華麗に扱うことができるようになったのではないでしょうか。それでは。

環境

  • NodeJS: v11.13.0
  • create-react-app: 2.1.8
  • bootstrap: 4.3.1
  • reactstrap: 8.0.0
  • formik: 1.5.2
  • yup: 0.27.0

カテゴリ : 技術 Tips & Tutorials タグ : formik, react, yup

2019年4月5日 By KD コメントを書く

React Hooksを試してみよう!(useStateとuseEffect編)

React Hooksを試してみよう!(useStateとuseEffect編)

Reactの注目の新機能であるReact Hooksをニュース検索アプリケーションを題材にして従来の方法と比較しながら試してみましょう。

はじめに

React Hooksはリリース前から話題になっていた新機能であり、私もベータ版の段階からサンプルを実装して試したりしていました。ざっくりと言うと、クラスベースから関数ベースの実装にするための機能です。他のプログラミング言語でも流行っている関数型プログラミングにフォーカスする形に進化したと考えて良いでしょう。

今回はニュースを検索する簡単なReactアプリケーションを従来のクラスベースで実装し、新機能のReact Hooksで再実装する形で試していきましょう。

React Hooksとは?

React Hooksとは、React 16.8で新しく追加された新機能で、従来Reactでクラスベースで実装していたことを関数ベースで実装することができるようになります。コーディングがシンプルにできるようになり、かつ、React特有のコンポーネントの状態管理を簡単にする利点があります。

今回はHooksの中でも基本となる「useState」と「useEffect」を使うことにします。

前提

以下の準備が完了している必要があります。

  • NodeJSがインストールされていること。
  • create-react-appがインストールされていること。
  • News APIのAPI keyを取得していること。(登録することで無料で取得できます。)

詳しいバージョンは「環境」を参照してください。

ニュースを検索するアプリケーションの作成(クラスベース)

まずは、従来のクラスベースの方法で実装してみましょう。

ベースを作る

まずは、ベースとなるフォルダを作成し、必要なパッケージをインストールします。

$ npx create-react-app news-search-app
$ cd news-search-app/
$ rm src/App.css 
$ rm src/App.test.js
$ rm src/logo.svg
$ yarn add axios bootstrap reactstrap
$ touch .env
$ tree -aI 'node_modules|.git'
.
├── .env
├── .gitignore
├── README.md
├── package.json
├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
├── src
│   ├── App.js
│   ├── index.css
│   ├── index.js
│   └── serviceWorker.js
└── yarn.lock

なお、今回はデザイン用にBootstrap4のReactコンポーネントである「reactstrap」を利用します。

実装する

サクサク実装してきましょう。

.env

REACT_APP_API_KEY=your-api-key

事前に取得したAPI keyを設定します。

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

serviceWorker.unregister();

BootstrapのCSSをインポートしておきます。

index.css

body {
text-align: center;
font-size: 20px;
padding: 2.5%;
}

簡単なCSSを書いておきます。

App.js

import React, { Component } from 'react';
import axios from 'axios';
import {
Form,
Input,
Button,
InputGroup,
Card,
CardImg,
CardTitle,
} from 'reactstrap';
const api = axios.create({
baseURL: 'https://newsapi.org/v2/everything/',
timeout: 1000,
headers: { 'X-Api-Key': process.env.REACT_APP_API_KEY },
});
class App extends Component {
state = {
searchWord: 'React Hooks',
articles: [],
query: '?q=React Hooks',
};
componentDidMount() {
document.title = `Searching by ${this.state.searchWord}`;
this.getArticles();
}
componentDidUpdate() {
document.title = `Searching by ${this.state.searchWord}`;
}
componentWillUnmount() {
this.setState({
searchWord: 'React Hooks',
articles: [],
});
}
getArticles = async () => {
try {
const result = await api.get(this.state.query);
const articles = result.data.articles.map(article => ({
title: article.title,
url: article.url,
urlToImage: article.urlToImage,
}));
this.setState({
...this.state,
articles,
});
} catch (error) {
console.log(error);
this.setState({
searchWord: '',
articles: [],
});
}
};
handleSeachWord = e => {
this.setState({
searchWord: e.target.value,
});
};
handleSearchForm = e => {
e.preventDefault();
this.setState({
...this.state,
query: `?q=${this.state.searchWord}`,
});
this.getArticles();
};
render() {
const { searchWord, articles } = this.state;
return (
<>
<h2>News Search App</h2>
<Form onSubmit={this.handleSearchForm}>
<InputGroup className="mx-auto col-8" style={{ margin: 20 }}>
<Input
type="text"
value={searchWord}
placeholder="Type search word..."
onChange={this.handleSeachWord}
/>
<Button type="submit">Let's Search!</Button>
</InputGroup>
</Form>
<div className="d-flex flex-wrap justify-content-center">
{articles.map((article, index) => (
<div key={index}>
<a href={article.url} target="_blank" rel="noopener noreferrer">
<Card style={{ width: 400, height: 300, margin: 20 }}>
<CardImg
src={article.urlToImage}
alt={article.title}
top
width="100%"
height="250px"
/>
<CardTitle>{`${article.title.slice(0, 30)}...`}</CardTitle>
</Card>
</a>
</div>
))}
</div>
</>
);
}
}
export default App;

検索すると、News APIから記事情報を取得して、表示する簡単な実装です。後で、React Hooksと比較するために、コンポーネントの状態管理の関数をあえて使っています。

動作確認する

それでは、アプリケーションを起動し、検索してみましょう。

$ yarn start

「JavaScript 2019」で検索してみます。

NewImage

検索結果が想定どおりに表示されました。OKです。

ニュースを検索するアプリケーションの作成(React Hooksで再実装)

それでは、React Hooksを使ってApp.jsを書き直しましょう。

React Hooksによる再実装

今回はReact HooksのuseStateとuseEffectを使って再実装し、できるだけ関数に切り出す形にします。

App.js

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import {
Form,
Input,
Button,
InputGroup,
Card,
CardImg,
CardTitle,
} from 'reactstrap';
const api = axios.create({
baseURL: 'https://newsapi.org/v2/everything/',
timeout: 1000,
headers: { 'X-Api-Key': process.env.REACT_APP_API_KEY },
});
const App = () => {
const [searchWord, setSearchWord] = useState('React Hooks');
const [articles, setArticles] = useState([]);
const [query, setQuery] = useState('?q=React Hooks');
const getArticles = async () => {
try {
const result = await api.get(query);
const newArticles = result.data.articles.map(article => ({
title: article.title,
url: article.url,
urlToImage: article.urlToImage,
}));
setArticles(newArticles);
} catch (error) {
console.log(error);
setSearchWord('');
setArticles([]);
}
};
useEffect(() => {
document.title = `Searching by ${searchWord}`;
getArticles();
}, [query]);
const handleSeachWord = e => {
setSearchWord(e.target.value);
};
const handleSearchForm = e => {
e.preventDefault();
setQuery(`?q=${searchWord}`);
};
const newsSearchForm = () => (
<Form onSubmit={handleSearchForm}>
<InputGroup className="mx-auto col-8" style={{ margin: 20 }}>
<Input
type="text"
value={searchWord}
placeholder="Type search word..."
onChange={handleSeachWord}
/>
<Button type="submit">Let's Search!</Button>
</InputGroup>
</Form>
);
const showArticles = () => (
<div className="d-flex flex-wrap justify-content-center">
{articles.map((article, index) => (
<div key={index}>
<a href={article.url} target="_blank" rel="noopener noreferrer">
<Card style={{ width: 400, height: 300, margin: 20 }}>
<CardImg
src={article.urlToImage}
alt={article.title}
top
width="100%"
height="250px"
/>
<CardTitle>{`${article.title.slice(0, 30)}...`}</CardTitle>
</Card>
</a>
</div>
))}
</div>
);
return (
<>
<h2>News Search App</h2>
{newsSearchForm()}
{showArticles()}
</>
);
};
export default App;

これでReact Hooksに対応しました!従来のクラスベースに比べてかなりソースコードの可読性が向上していますね。また、注目すべき点として、Reactのコンポーネントの状態管理用の関数(componentDidMount、componentDidUpdate、componentWillUnmount)がuseEffectで管理できるようになっている点です。これによりややこしい状態管理のコーディングのミスを減らすことができるでしょう。

動作確認

起動して、「Japan」で検索してみしょう。

NewImage

先ほどと同じ動作で動いていますね。

最後に

いかがでしたか?これでReact Hooksの基本であるuseStateとuseEffectの使い方が掴めたのではないかと思います。クラスベースよりもスッキリして使いやすいですよね。どんどん使っていきましょう。それでは。

環境

  • PC: macOS Mojava 10.14.3
  • NodeJS: v11.11.0
  • create-react-app: 2.1.8
  • react: 16.8.6

カテゴリ : 技術 Tips & Tutorials タグ : react, react-hooks

2019年3月11日 By KD コメントを書く

GatsbyJSをWordPressのHeadless CMSのREST APIと連携する方法(JWT認証編)

GatsbyJSをWordPressのHeadless CMSのREST APIと連携する方法(JWT認証編)

React製の静的サイトジェネレーターであるGatsbyJSと、Headless CMSとして機能するWordPressのREST APIを連携させて、バックエンドはWordPressで管理しつつ、フロントエンドをGatsbyJSで簡単に構築する方法を紹介します。

はじめに

最近注目を集めているReact製の静的サイトジェネレーターであるGatsbyJSと、デフォルトでHeadless CMSとして機能させることができるWordPressのREST APIを連携させることで、WordPressの管理画面の使い勝手を維持したまま、フロントエンドをモダンに書き換えることが可能です。CMSを構築する上で今最も暑い組み合わせです。さらに、今回はJWT認証の設定までさらっと完成させます。

それでは、GatsbyJSとWordPress REST APIを連携させて動かしてみましょう。

GatsbyJSとは?

GatsbyJSとは、ReactとGraphQLを前提とした静的サイトジェネレーターです。静的サイトなので、ページの表示の際にGraphQLで必要な情報を1回取得し、静的ページを生成して表示する仕組みです。開発はReactで行うことになります。

前提

以下の準備が完了している必要があります。

  • Dockerがインストールされていること
  • NodeJSがインストールされていること
  • WordPressのREST APIでJWT認証設定が完了している開発環境が構築済みであること(この環境がない人は以前の記事「WordPressのHeadless CMSのREST APIを使う開発環境をDocker上に構築する方法(JWT認証編)」を参照してください。)

詳しくは「環境」を参照してください。

WordPress REST APIとテストデータの準備

それでは、GatsbyJSとWordPress REST APIを連携していきましょう。

WordPressのREST APIを起動する

まずは、WordPress REST APIを起動します。WordPress REST APIの開発環境は以前の記事「WordPressのHeadless CMSのREST APIを使う開発環境をDocker上に構築する方法(JWT認証編)」から持ってきて使います。

$ cd wordpress-headless-cms
$ docker-compose up --build -d
$ docker-compose ps
Name              Command               State                 Ports              
---------------------------------------------------------------------------------
db     docker-entrypoint.sh --def ...   Up      0.0.0.0:3306->3306/tcp, 33060/tcp
web    docker-php-entrypoint apac ...   Up      80/tcp, 0.0.0.0:8080->8080/tcp

以前の記事のWordPressの設定がすべて完了している前提で進めますが、一応補足しておくと、以下の2つのプラグインのインストールと設定が必要です。

  • JWT Authentication for WP REST API
  • WP API Menus

WordPressにテストデータを入れる

今回用の固定ページおよびヘッダーメニューのテストデータを準備します。

$ docker exec web wp post delete $(docker exec web wp post list --post_type=page,post --format=ids)
$ docker exec web wp post create --post_type=page --post_title="Welcome Page" --post_content="Welcome to GatsbyJS page with WordPress;)" --post_name=welcom --post_status=publish
$ docker exec web wp post create --post_type=page --post_title="Test Page" --post_content="Let's getting started with GatsbyJS and WordPress Headless CMS\!" --post_name=test --post_status=publish
$ curl http://localhost:8080/wp-json/wp/v2/pages | jq
[
{
"id": 9,
...
"slug": "test",
"status": "publish",
"type": "page",
"link": "http://localhost:8080/test/",
"title": {
"rendered": "Test Page"
},
"content": {
"rendered": "

Let’s getting started with GatsbyJS and WordPress Headless CMS\\!

\n", "protected": false }, ... } }, { "id": 8, ... "slug": "welcome", "status": "publish", "type": "page", "link": "http://localhost:8080/welcome/", "title": { "rendered": "Welcome Page" }, "content": { "rendered": "

Welcome to GatsbyJS page with WordPress;)

\n", "protected": false }, ... } } ] $ docker exec web wp menu delete $(docker exec web wp menu list --format=ids) $ docker exec web wp menu create "Header menu" $ curl http://localhost:8080/wp-json/wp-api-menus/v2/menus | jq [ { "term_id": 2, "name": "Header menu", "slug": "header-menu", ... "meta": { "links": { "collection": "http://localhost:8080/wp-json/wp-api-menus/v2/menus/", "self": "http://localhost:8080/wp-json/wp-api-menus/v2/menus/2" } } } ] $ docker exec web wp menu item add-post header-menu 8 --title="Welcome" $ docker exec web wp menu item add-post header-menu 9 --title="Test Page"

WordPressの管理画面にログインして確認してみましょう。

NewImage

NewImage

大丈夫ですね。

GatsbyJSとWordPress REST APIの連携

GatsbyJSプロジェクトを作成する

GatsbyJSのプロジェクトを生成し、必要なプラグインをインストールします。

$ npm install -g gatsby-cli
$ gatsby new frontend
$ cd frontend/
$ npm install --save gatsby-source-wordpress slash dotenv
$ rm yarn.lock
$ rm src/pages/index.js
$ rm src/pages/page-2.js
$ mkdir -p src/templates
$ touch src/templates/page.js
$ touch .env
$ tree -a -I 'node_modules|.cache|public'
.
├── .env
├── .gitignore
├── LICENSE
├── README.md
├── gatsby-browser.js
├── gatsby-config.js
├── gatsby-node.js
├── gatsby-ssr.js
├── package-lock.json
├── package.json
└── src
├── components
│   ├── header.js
│   ├── image.js
│   ├── layout.css
│   ├── layout.js
│   └── seo.js
├── images
│   ├── gatsby-astronaut.png
│   └── gatsby-icon.png
├── pages
│   └── 404.js
└── templates
└── page.js

GatsbyJSとWordPressを連携するために「gatsby-source-wordpress」というプラグインをインストールしています。

GatsbyJSにWordPress連携の設定を追加する

GatsbyJSにWordPress連携の設定を追加しましょう。

.env

API_PROTOCOL=http
API_URL=localhost:8080
JWT_USER=wordpress
JWT_PASSWORD=wordpress

gatsby-config.js

require('dotenv').config();
module.exports = {
siteMetadata: {
title: `Gatsby Default Starter`,
description: `Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.`,
author: `@gatsbyjs`,
},
plugins: [
`gatsby-plugin-react-helmet`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`,
},
},
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `gatsby-starter-default`,
short_name: `starter`,
start_url: `/`,
background_color: `#663399`,
theme_color: `#663399`,
display: `minimal-ui`,
icon: `src/images/gatsby-icon.png`,
},
},
/*
* Gatsby's data processing layer begins with “source”
* plugins. Here the site sources its data from WordPress.
*/
{
resolve: 'gatsby-source-wordpress',
options: {
baseUrl: process.env.API_URL,
protocol: process.env.API_PROTOCOL,
hostingWPCOM: false,
useACF: false,
acfOptionPageIds: [],
auth: {
jwt_user: process.env.JWT_USER,
jwt_pass: process.env.JWT_PASSWORD,
jwt_base_path: '/jwt-auth/v1/token',
},
verboseOutput: false,
perPage: 100,
concurrentRequests: 10,
includedRoutes: [
'**/*/*/categories',
'**/*/*/posts',
'**/*/*/pages',
'**/*/*/media',
'**/*/*/tags',
'**/*/*/taxonomies',
'**/*/*/users',
'**/*/*/menus',
],
excludedRoutes: [],
normalizer({ entities }) {
return entities;
},
},
},
],
};

GatsbyJSのGraphiQL画面でWordPress連携を確認する

GatsbyJSを起動します。

$ gatsby develop

ブラウザで「http://localhost:8000/___graphql」にアクセスし、GraphQLでWordPressのページ情報「allWordpressPage」とヘッダーメニュー情報「allWordpressWpApiMenusMenusItems」を取得できるか確認します。

NewImage

{
pages: allWordpressPage {
edges {
node {
id
link
status
template
title
content
slug
}
}
}
headerMenuItems: allWordpressWpApiMenusMenusItems(filter: {slug: {eq: "header-menu"}}) {
edges {
node {
name
slug
items {
title
object_slug
}
}
}
}
}

GatsbyJSとWordPressとの連携が確認できました。

GatsbyJSの画面を少し作る

WordPressから取得したデータを表示させるだけの簡単なフロントエンドをGatsbyJSで作ります。

gatsby-node.js

const path = require('path');
const slash = require('slash');
exports.createPages = async ({ graphql, actions }) => {
const { createPage, createRedirect } = actions;
createRedirect({
fromPath: '/',
toPath: '/welcome',
redirectInBrowser: true,
isPermanent: true,
});
const result = await graphql(`
{
allWordpressPage {
edges {
node {
id
link
status
template
title
content
slug
}
}
}
}
`);
if (result.errors) {
throw new Error(result.errors);
}
const { allWordpressPage } = result.data;
const pageTemplate = path.resolve(`./src/templates/page.js`);
allWordpressPage.edges.forEach(edge => {
createPage({
path: `/${edge.node.slug}/`,
component: slash(pageTemplate),
context: edge.node,
});
});
};

page.js

import React from 'react';
import Layout from '../components/layout';
import SEO from '../components/seo';
export default ({ pageContext }) => (
<Layout>
<SEO title={pageContext.title} />
<h1 dangerouslySetInnerHTML={{ __html: pageContext.title }} />
<div dangerouslySetInnerHTML={{ __html: pageContext.content }} />
</Layout>
);

header.js

import React from 'react';
import { graphql, StaticQuery, Link } from 'gatsby';
const Header = ({ siteTitle }) => (
<StaticQuery
query={graphql`
{
allWordpressWpApiMenusMenusItems(
filter: { slug: { eq: "header-menu" } }
) {
edges {
node {
name
slug
items {
title
object_slug
}
}
}
}
}
`}
render={props => (
<header
style={{
background: `rebeccapurple`,
marginBottom: `1.45rem`,
}}
>
<div
style={{
margin: `0 auto`,
maxWidth: 960,
padding: `1.45rem 1.0875rem`,
}}
>
<h1 style={{ margin: 0 }}>
<Link
to="/"
style={{
color: `white`,
textDecoration: `none`,
}}
>
{siteTitle}
</Link>
</h1>
<div style={{ marginTop: `10px` }}>
{props.allWordpressWpApiMenusMenusItems.edges[0].node.items.map(
item => (
<Link
style={{
color: `white`,
padding: `10px`,
}}
to={item.object_slug}
key={item.title}
>
{item.title}
</Link>
),
)}
</div>
</div>
</header>
)}
/>
);
export default Header;

簡単ですが完成です。

動作確認

最後にGatsbyJSを起動してWordPressから取得した情報が表示されることを確認しましょう。

まずはGatsbyJSを起動します。

$ gatsby develop

ブラウザで「http://localhost:8000/」にアクセスすると、「http://localhost:8000/welcome」にリダイレクトされ、WordPressから取得したWelcomeページが表示されました。

NewImage

「Test Page」のリンクをクリックすると、「http://localhost:8000/test」に遷移し、WordPressから取得したTestページが表示されました。

NewImage

OKですね。

最後に

いかがでしたか?これでGatsbyJSとWordPressのHeadless CMSのREST APIを連携させることができるようになったと思います。今回は取得まででしたが、JWT認証も設定しているので、記事の作成や更新もできます。試してみると面白いと思います。それでは。

環境

  • Docker: 18.09.2, build 6247962
  • NodeJS: v11.10.0
  • gatsby-cli: 2.4.11

カテゴリ : 技術 Tips & Tutorials タグ : gatsbyjs, headless-cms, jwt, rest-api, wordpress

  • « 前のページ
  • 1
  • …
  • 3
  • 4
  • 5
  • 6
  • 7
  • …
  • 51
  • 次のページ »

ブログ更新情報や海外の関連情報などを配信する無料メルマガ

Sponsored Links

About Author

KD

世界を旅し日本を愛するエンジニア。大学でコンピュータサイエンスの楽しさを学び、日本の大手IT企業で働く中で、新しい技術やスケールするビジネスが北米にある事に気づく。世界に挑戦するための最大の壁が英語であったため、フィリピン留学およびカナダ留学を経て英語を上達させた。現在は日本在住でエンジニアとして働きつつ、次の挑戦に備えて世界の動向を注視している。挑戦に終わりはない。このブログでは、エンジニアやデザイナー向けの技術情報から、海外に留学したい人向けの留学情報、海外に興味がある人向けの海外旅行情報など、有益な情報を提供しています。

https://casualdevelopers.com/

最近の投稿

  • 2020年JS周辺のバックエンド寄りの注目技術!ネクストNodeJSの「Deno」と分散型パッケージレジストリの「Entropic」の紹介

    2020年JS周辺のバックエンド寄りの注目技術!ネクストNodeJSの「Deno」と分散型パッケージレジストリの「Entropic」の紹介

    2020年1月13日
  • 今さら聞けないJavaによる関数型プログラミング入門 ~ラムダ式、ストリーム、関数型インターフェース~

    今さら聞けないJavaによる関数型プログラミング入門 ~ラムダ式、ストリーム、関数型インターフェース~

    2019年11月4日
  • ReactのためのEslintおよびPrettierの設定方法 ~Airbnb JavaScript Style Guideの適用~

    ReactのためのEslintおよびPrettierの設定方法 ~Airbnb JavaScript Style Guideの適用~

    2019年10月30日
  • BashからZshに移行する方法(Mac編)

    BashからZshに移行する方法(Mac編)

    2019年10月21日
  • Create React Appを使わないでゼロからReactの開発環境を構築する方法(Webpack/Docker編)

    Create React Appを使わないでゼロからReactの開発環境を構築する方法(Webpack/Docker編)

    2019年9月30日

カテゴリ

  • 技術 Tips & Tutorials (100)
  • 技術塾 (6)
  • ライフハック (26)
  • 海外留学 (12)
  • 英語学習 (3)
  • コラム (6)

アーカイブ

最高の学習のために

人気記事ランキング

  • MySQLで「ERROR 2003 (HY000): Can't connect to MySQL server」と怒られた時の対処法
    MySQLで「ERROR 2003 (HY000): Can't connect to MySQL server」と怒られた時の対処法
  • Jupyter Notebookで「The kernel appears to have died. It will restart automatically.」というエラーが出た場合の原因と対処法
    Jupyter Notebookで「The kernel appears to have died. It will restart automatically.」というエラーが出た場合の原因と対処法
  • SAKURAのメールボックスで独自ドメインのメールを設定し、Gmail経由で送受信する方法
    SAKURAのメールボックスで独自ドメインのメールを設定し、Gmail経由で送受信する方法
  • バンクーバー留学豆知識:バンクーバーのATMで日本の銀行のキャッシュカードを使ってお得にお金を引き出す方法
    バンクーバー留学豆知識:バンクーバーのATMで日本の銀行のキャッシュカードを使ってお得にお金を引き出す方法
  • Amazon EC2インスタンスにSSHできなくなった時の対処法
    Amazon EC2インスタンスにSSHできなくなった時の対処法
  • Expressで「Cannot set headers after they are sent to the client」と怒られた時の対処法
    Expressで「Cannot set headers after they are sent to the client」と怒られた時の対処法
  • TumblrからWordPressにブログ移転する最適な方法
    TumblrからWordPressにブログ移転する最適な方法
  • SpringBootのProfile毎にプロパティを使い分ける3つの方法
    SpringBootのProfile毎にプロパティを使い分ける3つの方法
  • 爆速でJenkinsをマスターしよう(GitHubアカウント統合編) ~ JenkinsのGitHub Organizationの設定方法 ~
    爆速でJenkinsをマスターしよう(GitHubアカウント統合編) ~ JenkinsのGitHub Organizationの設定方法 ~
  • DockerコンテナのThe PID 1 Problemとその解決策(NodeJS編)
    DockerコンテナのThe PID 1 Problemとその解決策(NodeJS編)

Bitcoin寄付 / BTC Donation

Bitcoinを寄付しよう

BTC
Select Payment Method
Personal Info

Donation Total: BTC 0.0010

このブログの運営のためにBitcoinでの寄付を募集しています。お気持ち程度の寄付を頂けると管理者の励みになります。

Bitcoin寄付について知りたい方はこちらの記事へ

ビットコイン取引ならここ

  • ホーム
  • 技術 Tips & Tutorials
  • 技術塾
  • ライフハック
  • 海外留学
  • 英語学習
  • コラム
  • サイトマップ
  • タグ一覧
  • プライバシーポリシー
  • お問い合わせ

Copyright © 2023 KD - Casual Developers Notes