概要
webSiteをReactで作成します。
Reactの基本構造を理解し、Topページ・お問合せページのコンポーネントを作成します。
完成イメージ
プロジェクト作成
まず、プロジェクトを作成します。
作業フォルダを設置したい場所にコンソールで移動し下記コマンドを実行します。
react-websiteという名前のプロジェクトを作成しました。
npx create-react-app react-website
完了すると、プロジェクト名で作業フォルダができています。
フォルダに移動し、一旦開発サーバを起動してみます。
cd react-website
npm start
ローディングが完了すると自動的にブラウザが立ち上がりwebサイトが表示されます。
編集する
VisualStudioCodeでプロジェクトフォルダを開きボイラープレートを編集して不要な部分を削除していきます。
App.js ファイルはwebサイトのルートになります。
一旦 <div className="App">
内を削除してHOMEと表示させてみます。 logo.svg も利用しないのでimportを削除します。
import './App.css';
function App() {
return (
<div className="App">
<h1>Home</h1>
</div>
);
}
export default App;
変更を加えて保存するとすぐに反映されます(npm startしたままの状態の場合)。
TOP画面の作成
Top.js
TOP画面を作成します。
整理するためsrcフォルダの中にscreensというフォルダを作ります。
screenフォルダ内にTop.jsを作成します。
mkdir src/screens
touch src/screens/Top.js
top.jsに記述します。
これはReactコンポーネントの基本的な構造です。
Reactでは、どこでもコンポーネントをimportすることができます。
import React from "react";
const Top = () => {
return (
)
}
export default Top;
TOP画面に中身を追加します。
中身は簡易コーポレートサイトを作成するで作成したwebsiteのindex.htmlの中からコピーして作成します。
コピーするのは<header>〜</main>
です。
Reactでは一つのコンポーネントに複数の要素は入れられないので、フラグメント(<> </>
)で囲んで一つの要素にまとめます。
コピーして、top.jsのreturn ()内に貼り付けます。
textareaのrowsはHTMLとは異なり{}
で囲んで数値を指定します。
import React from "react";
const Top = () => {
return (
+ <>
+ <header class="top">
+ <h1 class="top_msg">bluecode, Lifestyle developer.</h1>
+ </header>
+ <main>
+ <section class="content">
+ <h2>websiteの最新情報</h2>
+ <p>最新の情報をご案内します。</p>
+ </section>
+ </main>
+ </>
)
}
export default Top;
<>
<header class="top">
<h1 class="top_msg">bluecode, Lifestyle developer.</h1>
</header>
<main>
<section class="content">
<h2>websiteの最新情報</h2>
<p>最新の情報をご案内します。</p>
</section>
</main>
</>
App.js
TOP画面を見えるようにするためには、App.jsにTOP.jsをインポートする必要があります。
そして、それをHTMLタグのように設定してレンダリングすることができます。
import './App.css';
+ import Top from './screens/Top';
function App() {
return (
<div className="App">
- <h1>Home</h1>
+ <Top />
</div>
);
}
export default App;
保存してブラウザを確認してみます。
スタイルが設定されていないので崩れていますが、コンテンツは表示できていることが確認できます。
App.css
スタイルを設定して確認してみます。
基本的にApp.cssに追加すれば適用されますが(App.jsで読み込んでいるため)、各コンポーネントで使うものについては分割してそれぞれコンポーネントで読み込むように記述していきます。
App.cssにはすべてのコンポーネントで共通するものを追加します。
一度App.cssの中身をすべて削除して必要なものを最終的なコードのstyle.cssから貼り付けます。
また、Reactでは、テンプレートですでに設定されているrootと表示する全体をまとめるAppというクラスがあるためこの2つについても高さを100%に指定しておきます(フッターが下に表示されるようにするため)
html {
height: 100%;
}
#root {
height: 100%;
}
.App {
height: 100%;
}
body {
margin: 0;
padding: 0;
font-family: sans-serif;
height: 100%;
}
Top.css
次にTop.js用のcssを作成してみます。
mkdir src/screens/styles
touch src/screens/styles/Top.css
.top {
/* 背景に取得した画像を設定 */
background-image: url("https://picsum.photos/1000/300");
/* 画像をいっぱいに表示 */
background-size: cover;
/* 表示する高さを画面の40%に */
height: 40vh;
/* 表示幅を画面の90%に */
width: 100%;
/* フレックスボックスを指定*/
display: flex;
/* フレックスアイテムを使って両端から中央に配置*/
justify-content: center;
/* フレックスアイテムを使って上下から中央に配置 */
align-items: center;
/* テキストの配置を中央揃えに */
text-align: center;
}
.top_msg {
/* 文字色を白に */
color: #fff;
}
.content {
width: 90%;
margin: 0 auto;
text-align: center;
}
Top.js
Top.cssをインポートします。
Reactではクラス名はclassNameとなるのでclass="xxx"
と記述している部分をすべてclassName="xxx"
の形式に変更します。
import React from "react";
+ import './styles/Top.css';
const Top = () => {
return (
<>
- <header class="top">
+ <header className="top">
- <h1 class="top_msg">bluecode, Lifestyle developer.</h1>
+ <h1 className="top_msg">bluecode, Lifestyle developer.</h1>
</header>
<main>
- <section class="content">
+ <section className="content">
<h2>websiteの最新情報</h2>
<p>最新の情報をご案内します。</p>
</section>
</main>
</>
)
}
export default Top;
<>
<header className="top">
<h1 className="top_msg">bluecode, Lifestyle developer.</h1>
</header>
<main>
<section className="content">
<h2>websiteの最新情報</h2>
<p>最新の情報をご案内します。</p>
</section>
</main>
</>
問合せ画面の作成
作成していきます。
必要となるファイルを作成していきます。
screens内にContact.js、stylesにContact.cssを作成します。
touch src/screens/Contact.js src/screens/styles/Contact.css
Contact.js
基本構造を記述します。
import React from "react";
const Contact = () => {
return (
)
}
export default Contact;
Top.js同様にフロントエンド開発の最終的なコードのContact.htmlから<main>〜</main>
をコピーして貼り付けます。
このとき、問合せ内容のtextareaで行を指定しているrows=4
について、記述がrows={4}
となるので変更しておきます。
import React from "react";
const Contact = () => {
return (
+ <main class="contact_form">
+ <h2>お問合せ</h2>
+ <form>
+ <div class="form_group">
+ <label>お名前</label>
+ <input type="text" id="name" />
+ <span class="form_error hidden" id="name_error">お名前は必須です。</span>
+ </div>
+ <div class="form_group">
+ <label>email</label>
+ <input type="email" id="email" />
+ <span class="form_error hidden" id="email_error">emailは必須かつemailの形式で入力してください。</span>
+ </div>
+ <div class="form_group">
+ <label>お問合せ内容</label>
+ <textarea id="body" rows={4}></textarea>
+ <span class="form_error hidden" id="body_error">お問合せ内容は必須かつ1文字以上10文字以下で入力してください。</span>
+ </div>
+ <button class="submit_btn" id="submit_btn">送信</button>
+ </form>
+ </main >
)
}
export default Contact;
<main class="contact_form">
<h2>お問合せ</h2>
<form>
<div class="form_group">
<label>お名前</label>
<input type="text" id="name" />
<span class="form_error hidden" id="name_error">お名前は必須です。</span>
</div>
<div class="form_group">
<label>email</label>
<input type="email" id="email" />
<span class="form_error hidden" id="email_error">emailは必須かつemailの形式で入力してください。</span>
</div>
<div class="form_group">
<label>お問合せ内容</label>
<textarea id="body" rows={4}></textarea>
<span class="form_error hidden" id="body_error">お問合せ内容は必須かつ1文字以上10文字以下で入力してください。</span>
</div>
<button class="submit_btn" id="submit_btn">送信</button>
</form>
</main >
App.js
App.jsでインポートします。
import './App.css';
import Top from './screens/Top';
+ import Contact from './screens/Contact';
function App() {
return (
<div className="App">
<Top />
+ <Contact />
</div>
);
}
export default App;
Contact.css
Contactコンポーネントで使っているものについてcssを記述します。
エラー文言の表示はcssで制御しなくなるため、.hiddenは不要になるので一旦cssからも削除しておきます。
.contact_form {
padding: 40px 20px;
text-align: center;
}
.form_group {
border-top: 1px solid #ddd;
margin-top: 20px;
padding: 20px 0px;
width: 100%;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.form_group label {
width: 30%;
font-weight: bold;
font-size: 18px;
}
.form_group input,
.form_group textarea {
border: 1px solid #ddd;
border-radius: 6px;
width: 60%;
font-size: 18px;
}
.form_group input {
height: 40px;
}
.submit_btn {
padding: 5px 15px;
background-color: #049dbf;
color: #fff;
border-radius: 5px;
border: 0;
font-size: 16px;
}
.submit_btn:hover {
background-color: #0183a0;
}
.form_error {
padding-left: 30%;
width: 60%;
font-size: small;
color: red;
text-align: start;
padding-top: 10px;
}
/*スマホ対応*/
@media screen and (max-width: 640px) {
/* お問合せフォーム */
.form_group label {
width: 100%;
padding-bottom: 10px;
}
.form_group input,
.form_group textarea {
width: 100%;
margin: 0;
padding: 0;
}
.submit_btn {
width: 100%;
height: 50px;
}
.form_error {
width: 100%;
text-align: left;
padding: 5px 0;
}
}
Contac.js
Contact.cssをインポートして、class
をclassName
に変更します。
import React from "react";
import './styles/Contact.css';
const Contact = () => {
return (
<main className="contact_form">
<h2>お問合せ</h2>
<form>
<div className="form_group">
<label>お名前</label>
<input type="text" id="name" />
<span className="form_error hidden" id="name_error">お名前は必須です。</span>
</div>
<div className="form_group">
<label>email</label>
<input type="email" id="email" />
<span className="form_error hidden" id="email_error">emailは必須かつemailの形式で入力してください。</span>
</div>
<div className="form_group">
<label>お問合せ内容</label>
<textarea id="body" rows={4}></textarea>
<span className="form_error hidden" id="body_error">お問合せ内容は必須かつ1文字以上10文字以下で入力してください。</span>
</div>
<button className="submit_btn" id="submit_btn">送信</button>
</form>
</main >
)
}
export default Contact;
保存して確認します。
TOP画面をスクロールすると、下にお問い合わせができています。
これで、Topページとお問合せページのコンポーネントは完成です。
最終的なコード
App.js
import './App.css';
import Top from './screens/Top';
import Contact from './screens/Contact';
function App() {
return (
<div className="App">
<Top />
<Contact />
</div>
);
}
export default App;
Top.css
.top {
/* 背景に取得した画像を設定 */
background-image: url("https://picsum.photos/1000/300");
/* 画像をいっぱいに表示 */
background-size: cover;
/* 表示する高さを画面の40%に */
height: 40vh;
/* 表示幅を画面の90%に */
width: 100%;
/* フレックスボックスを指定*/
display: flex;
/* フレックスアイテムを使って両端から中央に配置*/
justify-content: center;
/* フレックスアイテムを使って上下から中央に配置 */
align-items: center;
/* テキストの配置を中央揃えに */
text-align: center;
}
.top_msg {
/* 文字色を白に */
color: #fff;
}
.content {
width: 90%;
margin: 0 auto;
text-align: center;
}
Contact.css
.contact_form {
padding: 40px 20px;
text-align: center;
}
.form_group {
border-top: 1px solid #ddd;
margin-top: 20px;
padding: 20px 0px;
width: 100%;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.form_group label {
width: 30%;
font-weight: bold;
font-size: 18px;
}
.form_group input,
.form_group textarea {
border: 1px solid #ddd;
border-radius: 6px;
width: 60%;
font-size: 18px;
}
.form_group input {
height: 40px;
}
.submit_btn {
padding: 5px 15px;
background-color: #049dbf;
color: #fff;
border-radius: 5px;
border: 0;
font-size: 16px;
}
.submit_btn:hover {
background-color: #0183a0;
}
.form_error {
padding-left: 30%;
width: 60%;
font-size: small;
color: red;
text-align: start;
padding-top: 10px;
}
/*スマホ対応*/
@media screen and (max-width: 640px) {
/* お問合せフォーム */
.form_group label {
width: 100%;
padding-bottom: 10px;
}
.form_group input,
.form_group textarea {
width: 100%;
margin: 0;
padding: 0;
}
.submit_btn {
width: 100%;
height: 50px;
}
.form_error {
width: 100%;
text-align: left;
padding: 5px 0;
}
}
Top.js
import React from "react";
import './styles/Top.css';
const Top = () => {
return (
<>
<header className="top">
<h1 className="top_msg">bluecode, Lifestyle developer.</h1>
</header>
<main>
<section className="content">
<h2>websiteの最新情報</h2>
<p>最新の情報をご案内します。</p>
</section>
</main>
</>
)
}
export default Top;
Contact.js
import React from "react";
import './styles/Contact.css';
const Contact = () => {
return (
<main className="contact_form">
<h2>お問合せ</h2>
<form>
<div className="form_group">
<label>お名前</label>
<input type="text" id="name" />
<span className="form_error hidden" id="name_error">お名前は必須です。</span>
</div>
<div className="form_group">
<label>email</label>
<input type="email" id="email" />
<span className="form_error hidden" id="email_error">emailは必須かつemailの形式で入力してください。</span>
</div>
<div className="form_group">
<label>お問合せ内容</label>
<textarea id="body" rows={4}></textarea>
<span className="form_error hidden" id="body_error">お問合せ内容は必須かつ1文字以上10文字以下で入力してください。</span>
</div>
<button className="submit_btn" id="submit_btn">送信</button>
</form>
</main >
)
}
export default Contact;