対応前後の差分
右下のタグ群のコンポーネントを作成する
作成するファイル
タグ一覧を表示するコンポーネント TagList を作成する
新規作成するファイル
TagList/
- index.js
- TagList.js
- TagList.module.scss
※既存のプロジェクトの構成をそのまま踏襲
index.js
// @flow
export { default } from './TagList';
TagList.js
useStaticQueryで、全Tagを取得して、mapでliタグとして追加していく処理
// @flow
import React from 'react';
import kebabCase from 'lodash/kebabCase';
import { Link } from 'gatsby';
import { useTagsList } from '../../../hooks';
import styles from './TagList.module.scss';
const TagList = () => {
const tags = useTagsList();
return (
<div className={styles['tag']}>
<ul className={styles['tag__list']}>
{tags.map((tag) => (
<li className={styles['tag__list-item']} key={tag.fieldValue}>
<Link className={styles['tag__list-item-link']} to={`/tag/${kebabCase(tag.fieldValue)}/`} >
{tag.fieldValue}
</Link>
</li>
))}
</ul>
</div>
);
};
export default TagList;
TagList.module.scss
リスト表示を横並びにするためにflex指定し、リストタグ関連のデフォルトの装飾を無効にして他はよしなにデザイン装飾。
(scss自体を似たようなコンポーネントからコピペして修正して対応してます。)
@import '../../../assets/scss/variables';
@import '../../../assets/scss/mixins';
.tag {
@include margin-bottom(1);
&__list {
display: flex;
flex-flow: row wrap;
flex-grow: 0;
flex-shrink: 0;
list-style: none;
padding: 0;
margin: 10px -3px;
background:none;
border-radius: none;
box-shadow: none;
&-item {
padding: 2px;
margin: 4px;
display: flex;
align-content: center;
align-items: center;
justify-content: center;
height: $button-height;
line-height: $button-height;
background-color: $color-gray-light;
text-align: center;
&-link {
border: 0;
display: flex;
color: $color-base;
font-size: 9px;
align-content: center;
align-items: center;
&:hover,
&:focus {
color: $color-gray;
}
}
}
}
}
Sidebarコンポーネントに追加
Sidebar内のContactsコンポーネントの下に配置して完了。
const Sidebar = ({ isIndex }: Props) => {
const { author, copyright, menu } = useSiteMetadata();
return (
<div className={styles['sidebar']}>
<div className={styles['sidebar__inner']}>
<Author author={author} isIndex={isIndex} />
<Menu menu={menu} />
<Contacts contacts={author.contacts} />
<TagList />
<Copyright copyright={copyright} />
</div>
</div>
);
};
タグを全て取得する処理(useStaticQuery)
ページ以外のコンポーネントなので、普通のgraphqlのクエリが使えない。
そのため、以下のような、ページ以外でもgraphqlクエリが使える useStaticQuery を使う。
import React from "react"
import { useStaticQuery, graphql } from "gatsby"
const NonPageComponent = () => {
const data = useStaticQuery(graphql`
query NonPageQuery {
site {
title
}
}
`)
return (
<h1>
{data.site.title}
</h1>
)
}
全タグ取得処理(useStaticQuery利用)が、定義済みだったのでそれを使った
src > hooks 配下に、 use-tag-list.js が作成されていて、全タグ取得のクエリが定義済みだったので、これをそのまま使いました。
// @flow
import { useStaticQuery, graphql } from 'gatsby';
const useTagsList = () => {
const { allMarkdownRemark } = useStaticQuery(
graphql`
query TagsListQuery {
allMarkdownRemark(
filter: { frontmatter: { template: { eq: "post" }, draft: { ne: true } } }
) {
group(field: frontmatter___tags) {
fieldValue
totalCount
}
}
}
`
);
return allMarkdownRemark.group;
};
export default useTagsList;
useStaticQueryファイルの置き場所
src > hooks 配下には、取得したいデータごとのクエリが書いてあるファイルが配置されている状態。
それぞれ、サイトの基本情報、全カテゴリ、全タグを取得する処理が定義されていた。
src > hooks
> use-site-metadata.js
> use-categories-list.js
> use-tags-list.js
use-site-metadata.jsの中身
// @flow
import { useStaticQuery, graphql } from 'gatsby';
const useSiteMetadata = () => {
const { site } = useStaticQuery(
graphql`
query SiteMetaData {
site {
siteMetadata {
author {
name
bio
photo
contacts {
# email
# telegram
twitter
# github
# rss
# vkontakte
}
}
menu {
label
path
}
url
title
subtitle
copyright
disqusShortname
}
}
}
`
);
return site.siteMetadata;
};
export default useSiteMetadata;
useStaticQueryファイルの使い方
上記のファイルを使って、データ取得する流れは以下
1: 定義済みクエリをimportする
2: クエリ結果を変数に格納し、ドット「.」でアクセスして使う
例) useSiteMetadata
// 1: hooksのパスを指定して、const定義した値(useSiteMetadata)をimportする
import { useSiteMetadata } from '../../../hooks';
const Author = () => {
// author変数に取得したデータを格納する
const { author } = useSiteMetadata();
return (
<div className={styles['author']}>
// 2: author変数に、ドット[.]で該当データにアクセスして取り出す
<strong>{author.name}</strong>
</a>
</p>
</div>
);
};
export default Author;
終わりに
スターターで立ち上げたプロジェクトなので、すでに有識者のコードが定義されているので、その処理を見るだけでも学びがある。
記事一覧画面をテキストだけじゃなく、画像+説明文というようなOGPのようなコンポーネント並べるような修正をしたいし、あれもしたいし、これもしたい。()