0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Reactの基礎2

Last updated at Posted at 2022-09-11

の続きです。

変数の導入

ベースのコード:

index.js
import React from 'react';
import ReactDOM from 'react-dom/client';

function HelloWorld(){
  return (
    <h1>Hello World!</h1>
  );
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<HelloWorld/>);

{ }で囲んだものをhrml形式のところに書くと、それは変数として認識されます。

例えば次のコードでは名前と苗字、現在の時刻を変数として付け加えてみました。

index.js
import React from 'react';
import ReactDOM from 'react-dom/client';

function HelloWorld(){
  const firstName = "Joe";
  const lastName = "Schmoe";

  const date = new Date();
  const hours = date.getHours()%12;
  return (
    <div>
      <h1>Hello {firstName} {lastName}!</h1>
      <h1>It is currently about {hours} o'clock!</h1>
    </div>
  );
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<HelloWorld/>);

出力は次のようになります。(僕はとある日の3時に実行したのでこのようになりました。)

image.png

もう少し複雑にして、例えばあいさつをするページにします。

index.js
import React from 'react';
import ReactDOM from 'react-dom/client';

function TimeOfDay(){
  const date = new Date();
  const hours = date.getHours();
  let timeOfDay;

  if(hours<12) timeOfDay = "morning";
  else if(hours<17) timeOfDay = "afternoon";
  else timeOfDay = "night";
  return timeOfDay;
};

function Hello(){
  const timeOfDay = TimeOfDay();
  return (
      <h1>Good {timeOfDay}!</h1>
  );
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Hello/>);

出力は

image.png

となり、現在は午後3時なのでOKです。

html上での関数の引数

< />で関数をhtml上で呼び出すことができました。これに引数を与えたいときは次のサンプルコードのようにします。cat*.pngはいらすとやから適当にとってきた猫のイラストです。また、電話やメールのロゴもネット上に落ちているものを適当にとってきました。次のような出力をするコードになっています。

image.png

関数Contactの中身が枠で囲った各猫のカードに表示するものに対応していてそれを4種の猫について作りました。同じものを表示するので
img:画像へのパス
name:猫の名前
phone:飼い主の電話番号
email:飼い主のメアド
を引数として与えた関数にしています。string型はそのまま代入しても大丈夫ですが、それ以外は{ }で囲まないといけません。ここではimgだけがstringでないので{ }で囲む必要があります。

index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './style.css';

import cat1 from "./images/cat1.png";
import cat2 from "./images/cat2.png";
import cat3 from "./images/cat3.png";
import cat4 from "./images/cat4.png";
import phoneIcon from "./images/phone-icon.png";
import mailIcon from "./images/mail-icon.png";

//表示する各カードの中身
//prop:引数のオブジェクト
function Contact(props) {
  return (
      <div className="contact-card">
          <img src={props.img} alt="cat"/>
          <h3>{props.name}</h3>
          <div className="info-group">
              <img src={phoneIcon} alt="icon" />
              <p>({props.phone}</p>
          </div>
          <div className="info-group">
              <img src={mailIcon} alt="icon"/>
              <p>{props.email}</p>
          </div>
      </div>
  )
};

function App(){
  return (
    <div className="contacts">
    //引数つき
    <Contact 
        img={cat1}
        name="Mr. Whiskerson"
        phone="(212) 555-1234"
        email="mr.whiskaz@catnap.meow"
    />
    <Contact 
        img={cat2}
        name="Fluffykins"
        phone="(212) 555-2345"
        email="fluff@me.com"
    />
    <Contact 
        img={cat3}
        name="Felix"
        phone="(212) 555-4567"
        email="thecat@hotmail.com"
    />
    <Contact 
        img={cat4}
        name="Pumpkin"
        phone="(0800) CAT KING"
        email="pumpkin@scrimba.com"
    />
  </div>
  );
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);

ちなみにこの節では本質的ではありませんがcssファイルの方は以下のようになっています。

style.css
* {
    box-sizing: border-box;
}

body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    align-items: center;
    font-family: 'Inter', sans-serif;
    background-color: whitesmoke;
}

.contacts {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 40px;
}

.contact-card {
    flex-basis: 225px;
    box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.25);
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    padding: 13px;
    padding-bottom: 20px;
    background-color: white;
}

.contact-card > img {
    width: 100%;
    height: auto;
    align-self: center;
    border-radius: 5px;
    object-fit: cover;
}

.contact-card > h3 {
    font-weight: 700;
    font-size: 18px;
}

.info-group {
    display: flex;
    align-items: center;
}

.info-group > img {
    height: 11px;
    margin-right: 8px;
}

.info-group > p {
    margin-block: 3px;
    font-size: 12px;
    color: #2B283A;
}

ちなみにContentは次のような書き方をすれば、引数にprop.を付けなくて済みます。

index.js
function Contact({img,name,phone,email}) {
  return (
      <div className="contact-card">
          <img src={img} alt="cat"/>
          <h3>{name}</h3>
          <div className="info-group">
              <img src={phoneIcon} alt="icon" />
              <p>({phone}</p>
          </div>
          <div className="info-group">
              <img src={mailIcon} alt="icon"/>
              <p>{email}</p>
          </div>
      </div>
  )
};

条件分岐

引数の中身が空でないならば表示する、というときには次のようにします。ここではメアドと電話に対してこの条件分岐を設定しました。2通りの書き方でやりましたが、1つ目のやり方の方が簡単だと思います。

index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './style.css';

import cat1 from "./images/cat1.png";
import cat2 from "./images/cat2.png";
import cat3 from "./images/cat3.png";
import cat4 from "./images/cat4.png";
import phoneIcon from "./images/phone-icon.png";
import mailIcon from "./images/mail-icon.png";

function Contact({img,name,phone,email}) {
  return (
      <div className="contact-card">
          <img src={img} alt="cat"/>
          <h3>{name}</h3>
            //条件分岐の書き方1
          {phone && <div className="info-group">
              <img src={phoneIcon} alt="icon" />
              <p>({phone}</p>
          </div>}
            //条件分岐の書き方2
          <div style={{display: email ? "block" : "none"}} className="info-group">
              <img src={mailIcon} alt="icon"/>
              <p>{email}</p>
          </div>
      </div>
  );
};

function App(){
  return (
    <div className="contacts">
    <Contact 
        img={cat1}
        name="Mr. Whiskerson"
        phone="(212) 555-1234"
        email="mr.whiskaz@catnap.meow"
    />
    <Contact 
        img={cat2}
        name="Fluffykins"
        phone="(212) 555-2345"
        email="fluff@me.com"
    />
    <Contact 
        img={cat3}
        name="Felix"
        phone="(212) 555-4567"
    />
    <Contact 
        img={cat4}
        name="Pumpkin"
        email="pumpkin@scrimba.com"
    />
  </div>
  );
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);

出力:

image.png

入力していなかった3匹目のメアドと4匹目の電話番号だけ非表示になっています。

画像のパスの読み込み

ちなみに画像のパスはヘッダで読み込まなくてもrequire関数でも読み込めるので次のような書き方もできます。

index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './style.css';

function Contact({img,name,phone,email}) {
    const catImgPath = require(`./images/${img}`);
    const phoneIconPath = require("./images/phone-icon.png");
    const emailIconPath = require("./images/mail-icon.png");

    return (
        <div className="contact-card">
            <img src={catImgPath} alt="cat"/>
            <h3>{name}</h3>
            {phone && <div className="info-group">
                <img src={phoneIconPath} alt="icon" />
                <p>({phone}</p>
            </div>}
            {email && <div className="info-group">
                <img src={emailIconPath} alt="icon"/>
                <p>{email}</p>
            </div>}
        </div>
    );
};

function App(){
  return (
    <div className="contacts">
    <Contact 
        img="cat1.png"
        name="Mr. Whiskerson"
        phone="(212) 555-1234"
        email="mr.whiskaz@catnap.meow"
    />
    <Contact 
        img="cat2.png"
        name="Fluffykins"
        phone="(212) 555-2345"
        email="fluff@me.com"
    />
    <Contact 
        img="cat3.png"
        name="Felix"
        phone="(212) 555-4567"
        email="thecat@hotmail.com"
    />
    <Contact 
        img="cat4.png"
        name="Pumpkin"
        phone="(0800) CAT KING"
        email="pumpkin@scrimba.com"
    />
  </div>
  );
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);

参考記事

と同じものを参考にしています。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?