Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8902

新人に負けない本棚管理サイト その3(トップページ作成編)

$
0
0

目次

新人に負けない本棚管理サイト その1(プロローグ)
新人に負けない本棚管理サイト その2(環境構築編)
[新人に負けない本棚管理サイト その3(ページ作成編)]

目標

トップページの見た目と他ページへの遷移だけ完成させます。
裏側の処理は次回実装します。

react-bootstrapの準備

イイカンジの見た目をサクッと作るために、本家bootstrapをComponentとして使えるようにしたreact-bootstrapを使っていきます。
そのための準備があるので最初にやります。
参考サイト:Next.js(React)でCSSとSASS(SCSS)、Bootstrapを使う

モジュールの追加

$ npm install react-bootstrap bootstrap @zeit/next-css @zeit/next-sass node-sass

Next.jsの設定(必要?)

※ この設定は私の場合していないのですが、特に問題なく動作しています。
※ 必要なのかどうか教えて下さい!!

Next.jsでは各Componentを定義しているjsファイルで静的にCSSファイルをincludeすることができません。(ターミナルにWARNINGが出ます)
index.jsもインデックスComponentという扱いになる(たぶん)ので、CSSをincludeすることがきません。
そこでプロジェクトフォルダ直下にnext.config.jsというファイルを作り、下の内容を書きます。

/next.config.js
constwithCss=require('@zeit/next-css');constwithSass=require('@zeit/next-sass');module.exports=withCss(withSass);

これがNext.js全体の設定になります。

ページ全体の設定

全ページでbootstrapのCSSを適用させる設定を書きます。
pages/_app.jsを新規作成し、下の内容を書きます。

pages/_app.js
import'bootstrap/dist/css/bootstrap.min.css';exportdefaultfunctionMyApp({Component,pageProps}){return<Component{...pageProps}/>}

トップページを作ろう!

雑すぎて草も生えない構想

layout.png

パーツ分けして構想をつくった理由

ReactではComponentというものを組み合わせてページを作っていきます。
画面をつくるパーツみたいなものです。
構想の図でいうと

  • ヘッダー
  • タイトル
  • 検索条件
  • 検索ボタン
  • 検索結果
  • フッター

がComponentに当たります。

またComponentを組み合わせてComponentをつくることもできます。
例えばタイトル、検索条件、検索結果を組み合わせてコンテンツComponentにまとめることができます。
こうすることにより、ページの構造を

  • ヘッダー
  • コンテンツ
    • タイトル
    • 検索条件
    • 検索ボタン
    • 検索結果

のように階層的に分解することができます。
これらを1つずつ作っていき、最終的にpages/index.jsで組み立てれば、あとはNext先生がよしなにやってくれるわけです。

Componentづくり

Componentはpagesフォルダではなく、プロジェクトフォルダの直下にcomponentsフォルダを作って配置します。
フォルダ名は何でもいいのでkusahaetaフォルダでもいいのですが、ひとまずcomponentsが無難かなぁ。

そしてなんと、Next.jsにはHotReload機能がついています。
この時点でnpm run devしておくと、これからソースコードを書き換えるだけで勝手にコンパイルされてブラウザの表示内容が勝手に変わります!
それだけで開発意欲がこれでもかっていうくらいブチ上げですね。
コンパイルエラーがある場合もブラウザに表示されますので、指摘されたところを直せばちゃんとした表示に勝手に切り替わります。

ヘッダー

いたって普通のヘッダーです。
左から「ロゴ」「Homeリンク」「Aboutリンク(自己紹介とか)」「外部リンクドロップダウン(Twitter,Qiita等)」を並べます。

ほとんど公式サイトのパクリなのでオリジナリティのカケラもない...
だがそこがいい!!(横着)

components/header.js
// Linkは後ほど解説importLinkfrom'next/link';// react-bootstrapから借りるComponentimport{Navbar,Nav,NavDropdown}from'react-bootstrap';exportdefaultfunctionHeader(){return(<div><Navbarfixed="top"variant="dark"bg="dark"expand="lg"><Navbar.Brand><imgclassName="nav-logo"src="/react-logo.svg"/></Navbar.Brand><Navbar.Togglearia-controls="basic-navbar-nav"/><Navbar.Collapseid="basic-navbar-nav"><NavclassName="mr-auto"><Linkhref="/"passHref><Nav.Link>Home</Nav.Link></Link><Linkhref="/about"passHref><Nav.Link>About</Nav.Link></Link><NavDropdowntitle="Link"><NavDropdown.Itemhref="https://twitter.com/##your_twitter_account##">Twitter</NavDropdown.Item><NavDropdown.Itemhref="https://qiita.com/##your_qiita_account##">Qiita</NavDropdown.Item></NavDropdown></Nav></Navbar.Collapse></Navbar></div>);}

ヘッダーの左端に表示するアイコンを表示させたいので、プロジェクトフォルダ直下にpublicフォルダをつくって画像を配置します。
Next.jsでは画像、CSS、JavaScriptはpublicフォルダに配置します。
publicフォルダへは/でアクセスできます。
画像名を<Nav.Brand>の中の<img>タグに書いてください。

2020-04-22 000401.png

次にトップページにヘッダーを追加します。

pages/index.js
// いま作ったヘッダーをインポートimportHeaderfrom'../components/header';exportdefaultfunctionIndex(){return(<div><Header/></div>);}

HotReloadがかかると...

2020-04-21 231247.png

こんな感じでヘッダーができあがります。
やっぱりbootstrapスゲェ!!大好き!!

本家bootstrap同様、モバイル端末の横幅ではヘッダーメニューがハンバーガーボタンにまとめられます。

2020-04-22 004550.png

(ヽ´ω`)<ロゴのバックが白でカッコワリィなぁ...

フッターは作りませんが同じ要領で作れます。

Componentを階層化

この後メインのコンテンツを作っていく前に、Componentを階層化することで作業を分割することにします。
どの粒度で階層化するかは人によると思いますが、私であれば1つのComponentに1つの役割の単位で階層化していきます。

まずページ全体のレイアウトを司るLayoutComponentをつくります。

components/layout.js
importHeaderfrom'./header';exportdefaultfunctionLayout(props){consttopMarginStyle={marginTop:"60px"};return(<div><Header/><divstyle={topMarginStyle}></div>{/*ヘッダーの高さ分余白をとる*/}{props.children}{/*この中にタイトルとかコンテンツとかが入る*/}</div>);}

そしてpages/index.jsにLayoutを適用します。

pages/index.js
//import Header from '../components/header';  削除importLayoutfrom../components/layout;exportdefaultfunctionIndex(){return(<div><Layout>{/* ここがLayoutComponentのprops.childrenに当たる場所 */}</Layout></div>);}

画面表示は変わりませんが、「まずヘッダーがあって次にコンテンツがある」というレイアウトは共通として切り出すことができました。
新しくページを作る場合、同様にLayoutComponentをimportすれば同じレイアウトで作ることができます。

コンテンツ

次に本棚管理ページ用のComponentを作ります。
componentsフォルダにbookmanagerフォルダを作って以下のようにします。

components/bookmanager/inputarea.js
importReactfrom'react';import{Button,Container,Row,Col,Form}from'react-bootstrap';exportdefaultclassInputAreaextendsReact.Component{render(){constconditionAreaStyle={padding:"40px 0px"};return(<Containerstyle={conditionAreaStyle}><Form><Form.GroupcontrolId="Booksearch"><Row><Colmd={1}><Form.Label>書籍名</Form.Label></Col><Colmd={5}><Form.Controltype="text"placeholder="例)PHP Python 入門"/></Col><Colmd={1}><Form.Label>著者名</Form.Label></Col><Colmd={5}><Form.Controltype="text"placeholder="ひらがなでもOKです"/></Col></Row></Form.Group><divclassName="text-right"><Buttonvariant="primary"type="submit">検索</Button></div></Form></Container>);}}
components/bookmanager/searchresult.js
importReactfrom'react';import{Container,Row,Col,Table}from'react-bootstrap';exportdefaultclassSearchResultextendsReact.Component{render(){return(<Container><Row><Tablestripedborderedsize="sm"><thead><tr><th>タイトル</th><th>著者名</th><th>出版社</th><th>読了日</th></tr></thead><tbody><tr><td>Python Django超入門</td><td>掌田津耶乃</td><td>秀和システム</td><td>2019/08/31</td></tr><tr><td>React.js&Next.js超入門</td><td>掌田津耶乃</td><td>秀和システム</td><td></td></tr><tr><td>PostgreSQL徹底入門 第4版</td><td>近藤雄太 他</td><td>翔泳社</td><td></td></tr><tr><td>PHPフレームワーク Laravel入門 第2版</td><td>掌田津耶乃</td><td>秀和システム</td><td>2019/10/31</td></tr><tr><td>PostgreSQLから始めるデータベース生活</td><td>まぐろ</td><td>まぐろのみぞおち</td><td>2019/11/03</td></tr></tbody></Table></Row></Container>);}}

完成!

kansei.png

見た目だけなので、検索ボタンを押すと404が出るし何かいろいろおかしいと思います。
次回裏側の処理を実装していきます。

そういえばLinkって何?

答)ハイラルの勇者です。(ニコニコ大百科

pose_ng_man.png

Linkとは、平たく言えば
Webサーバーへリクエストを送りレスポンスを受け取るという一連の処理を行うことなく
ページ遷移を行えるようにする

機能です。

つまり今開いているページから遷移することなく行き先のページを表示することができるのです!!
(怒られそうな書き方)

具体的に見てみよう

これは、本棚管理サイトを作るついでにいろんなサイトへ行けるようにつくったホームページです。

2020-04-22 002343.png

BookManagerをクリックします。

2020-04-22 002628.png

赤丸の中身が増えただけで新しいページに遷移できました。
がんばって説明すると

サーバーからレスポンスを受け取ってページを再構築したわけではなく、
遷移先のページを表示するために必要な分だけあるモジュールがページを書き換えた

ということが起きています。
いわゆる仮想DOMというものですが、説明が面倒なので参考サイトにお任せしちゃいます(´ω`)
なぜ仮想DOMという概念が俺達の魂を震えさせるのか

Next.jsでもLinkの使い方は説明されているので(英語ですが)ぜひご覧ください。

次回

データベースとのやりとりを作っていきます。
まずはデータベースからデータを持ってきてページに表示するところまでです。


Viewing all articles
Browse latest Browse all 8902

Trending Articles