1. ndj

    No comment

    ndj
Changes in body
Source | HTML | Preview
@@ -1,135 +1,159 @@
こんにちは、ndj です。
現在、勉強がてら `Gatsby.js` を使用して簡単なホームページを作成しています。
ヘッダーに言語を選択できる `select` ボックスを作成して、選択した言語に合わせてページを遷移したいなと思ったのですが、ハマってしまったので備忘録として残しておきます。
+(2021/03/01) 追記:navigate を使用する場合は、Router を使用しなくてもよいことがわかったので、「this.props.history.push ではなく、navigate() を使用する」部分のコード部分を修正。
+
## 使用技術とバージョン情報
- gatsby: 2.32.3
- gatsby-source-microcms: 1.0.1
- react-router-dom: 5.2.0
- react: 16.12.0
## 結論
- `React` 標準で使用される、`this.props.history.push` ではなく、`gatsby` の `navigate()` を使用する。
## やりたかったこと
amazon など、グローバルに使用されているサービスってヘッダーに言語情報を選択できるようになっていますよね。
![スクリーンショット 2021-02-23 231313.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485313/950e54ca-a894-7005-8d37-bfbe0fa48dd9.png)
amazon みたいに、言語情報を選択したら、その言語のページに遷移できるようにしたいなと。
## 試みたこと
当初は、以下のように、 `<select>`タグ の `onChange` イベントハンドラで `this.props.history.push(e.target.value)` をして、ページを遷移しようとしていました。
参考:[codesandbox.io: w031p82nr5](https://codesandbox.io/s/w031p82nr5?file=/src/index.js)
また、**言語別の説明文は headlessCMS に保存しており、ページ生成の際に、`gatsby-node.js` の `createPage` で `<Home />` に context を渡す**。みたいな感じでページを生成しておりました。
```header.js
import React from 'react';
import { useStaticQuery, Link, navigate } from 'gatsby';
import { Switch, Route, BrowserRouter as Router, withRouter } from 'react-router-dom';
import Home from '../pages/locale';
class DropDown extends React.Component {
onChange = (e) => {
this.props.history.push(`/${e.target.value}`);
}
render() {
return (
<select onChange={this.onChange}>
<option value="ja">日本語</option>
<option value="en">English</option>
</select>
);
}
}
const Menu = withRouter(DropDown);
export default function Header() {
return (
<Router>
<header className="header">
<nav>
<ul id="header-list">
<li>
<Menu />
</li>
<li>
<Link to="/">Install now</Link>
</li>
</ul>
</nav>
</header>
<Switch>
<Route path='/ja' render={() => <Home locale="ja" />} />
<Route path='/en' render={() => <Home locale="en" />} />
</Switch>
</Router>
);
}
```
こんな感じでページ遷移を実現させたかったんですが、エラーが出る。。。
```
Uncaught TypeError: Cannot read property 'post' of undefined
```
## 原因っぽい部分
エラー自体の原因は、以下の部分です。
```js
<Route path='/ja' render={() => <Home locale="ja" />} />
```
先述のように、言語別の説明文は headlessCMS に保存しており、ページ生成の際に、`gatsby-node.js` の `createPage` で `GraphQL query` を投げて、 `<Home />` に context を渡す。みたいな感じでページを生成しておりました。
つまり、上記のコードだと `select` ボックスの選択肢が変化したときに context を渡せないので、エラーが出てたという感じです。
なので、**ページ遷移の方法を工夫する必要がありそう**です。
## this.props.history.push ではなく、navigate() を使用する
`DropDown` の `onChange` の部分を以下のように変更します。
`gatsby` に専用の function があるみたいです。
参考:[gatsbyjs:How to use the navigate helper function](https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-link/#how-to-use-the-navigate-helper-function)
参考:[stackoverflow: What's the equivalent of this.props.history.push in gatsby?](https://stackoverflow.com/questions/58677568/whats-the-equivalent-of-this-props-history-push-in-gatsby)
```header.js
+import { Link, navigate } from 'gatsby';
+
class DropDown extends React.Component {
onChange = (e) => {
navigate(`/${e.target.value}`);
}
render() {
return (
<select onChange={this.onChange}>
<option value="ja">日本語</option>
<option value="en">English</option>
</select>
);
}
}
+
+export default function Header() {
+ return (
+ <React.Fragment>
+ <header className="header">
+ <nav>
+ <ul id="header-list">
+ <li>
+ <DropDown />
+ </li>
+ <li>
+ <Link to="/">Install now</Link>
+ </li>
+ </ul>
+ </nav>
+ </header>
+ </React.Fragment>
+
+ );
+}
```
## 最後に
`gatsby` もさることながら、 `React` 自体の習熟度も低く解決に時間がかかってしまいましたが、コツコツやっていきたいと思います。
また、今回解決方法を検索する際に積極的に英語のページを見るようにしましたが、翻訳機能様の存在とソースは全世界で共通なので頑張れば意外といけました。
誤字脱字、技術的なご指摘などございましたら、コメントいただけますとありがたいです。
ここまで読んでいただきありがとうございました。
これからも巨人の肩に乗り続けます。
## 参考
[amazon](https://www.amazon.co.jp/)
[codesandbox.io: w031p82nr5](https://codesandbox.io/s/w031p82nr5?file=/src/index.js)
[gatsbyjs:How to use the navigate helper function](https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-link/#how-to-use-the-navigate-helper-function)
[stackoverflow: What's the equivalent of this.props.history.push in gatsby?](https://stackoverflow.com/questions/58677568/whats-the-equivalent-of-this-props-history-push-in-gatsby)