Gatsby+Netlify+microCMS+Material UI 実装ではまったところ
タイトルの通りですが、Gatsby+Netlify+microCMS+Material UIで個人のwebサイトを作成しました。
まだ色々と修正したいところだらけなのですが、現状作ってきた中でハマったところを忘れないうちに書き留めておきます。
願わくば、同じような構成でwebサイトを作っている方のヒントになればと思います。
ということでソースコードも公開しています。
細かいところはおおめに見てください。
※注意※
細かい設定手順については色々なサイトで丁寧に解説しているので、省略させていただきますmm
WebpackError: ReferenceError: window is not defined
ローカル環境では動くけれど、Netlifyでデプロイしようとするとコケる。
20 | 21 | export default function ContentsContiner(props) { > 22 | const windowHeight = window.innerHeight; | ^ 23 | const classes = useStyles(windowHeight); 24 | return ( 25 | <Container fixed className={classes.container} id={props.id}> WebpackError: ReferenceError: window is not defined - contentContiner.jsx:22
こちらは調べるとわりとすぐ出てくるけれど、window
が取得できないらしい。
ので、手取り早く修正するのであればこんな感じでundefined
で一回判定を入れてあげれば解決します。
if ( typeof window !== 'undefined' ) { windowHeight = window.innerHeight; }
WebpackError: TypeError: Cannot read property 'allMicrocmsArt' of undefined
こちらも、ローカルではうまく動くけれども、Netlifyにデプロイするとコケるパターン。
allMicrocmsArt
はmicroCMSから取得しようとしている要素名です。
各々の環境で別の名称になってくると思います。
エラーが出た時の構成はこんな感じです。
./src/pages ├── about.tsx ├── art.tsx // 実際にdataを使用するコンポーネント ├── index.js ├── index.tsx // ここでgraphqlでdata取得 ├── skill.tsx └── top.tsx
index.tsxにかいていたコードはこんな感じです。
const App = ({data}) => { const classes = useStyles(); return ( <> <Header/> <Top id="top" /> <About id="about"/> // ↓↓↓↓丸ごとdataを渡している <Art data={data} /> <Skill id ="skill" /> <Footer/> <ScrollTop classes={classes} > </> )} export const query = graphql` query { allMicrocmsArt { nodes { id title createdAt picture { url } thumbnail { url } } } } ` export default App;
結局のところ、取得するデータがどこで使われるかを適切に判断し、必要なものを必要な場所で必要な分だけ取得してあげる必要があります。(それがgraphqlの良さでもありますしね)
エラー自体は親からもらったdataをそのまま子コンポーネントに渡していたので、型解決ができずに子コンポーネントで落ちると言った状況でした。
今回の場合、親コンポーネントは取得したallMicrocmsArt
を全く使用しないため、データは子コンポーネント内で取得されるべきでした。
そして、子コンポーネントで静的なデータとして使用する場合には、useStaticQuery
を使用するのが良いようです。
const Art = () => { const data = useStaticQuery( graphql` query { allMicrocmsArt { nodes { id title createdAt picture { url } thumbnail { url } } } } ` ) -- 中略 -- return ( <ContentsContiner id='art'> <Typography variant="h3" gutterBottom> art work. </Typography> <GridList cellHeight={160} className={classes.gridList} cols={col}> // ↓↓↓↓ この辺から {data.allMicrocmsArt.nodes.map( node => <GridListTile key={node.id} cols={1}> <img src={node.thumbnail.url} alt={node.title} className={classes.thumbnail} onClick={() => handleToggle(node.picture)} /> </GridListTile> )} </GridList> </ContentsContiner> ); } export default Art;
Qeryをコンポーネント内に記述するので少し長くなって読みにくくなるのはちょっといまいちだなぁとは思いますが、
こんな感じでuseStaticQuery
で取得した値をconst
に入れてあげればデータを取得することができます。
Material UIでCSSアニメーションを設定する
こちらは、以下の記事を参考にしました。ありがとうございます。
こんな感じです。
const useStyles = makeStyles((theme) => ({ image: { animation: '$fadeIn 1 1s linear' }, '@keyframes fadeIn': { from: { opacity: 0 }, to: { opacity: 1 } } }));
本当にメモ程度で恐縮です。
Netlifyちゃんと触ったの初めてだったのですが、設定簡単すぎて拝みました。
それとCMSにmicroCMSを採用した理由ですが、日本製だからというのが10割りです。
困ったときに母国語でドキュメントが整備されているのはこれ以上ないアドバンテージです。
管理画面も見やすくて推せます。
Material UIは今回レイアウトで結構うんうん唸ってたので、一から自分で作っても良かった説はありますが、
Reacのファイル内にCSSを記述する上でuseStylesが見やすくて好きなので、これで良かったのだと思います。
今後もウェブサイトの細かい修正は続いていくので、また何かあればかこうと思います。