Reactの基礎２

https://qiita.com/hiro949/items/855e64ba7934d1774d91

の続きです。

# 変数の導入

ベースのコード：

```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/>);
```

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2445529/9a3b781c-84de-9fc5-c137-359d5782b9fc.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2445529/19b2559d-bd94-d131-8ac7-7955666e199c.png)

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

# html上での関数の引数

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2445529/8e973766-60cb-6e0d-e83b-69a8521879f1.png)

関数Contactの中身が枠で囲った各猫のカードに表示するものに対応していてそれを４種の猫について作りました。同じものを表示するので
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>
  )
};
```

# 条件分岐

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

```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>
            //条件分岐の書き方１
          {phone && <div className="info-group">
              <img src={phoneIcon} alt="icon" />
              <p>({phone}</p>
          </div>}
            //条件分岐の書き方２
          <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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2445529/a7e91625-1693-d43f-2eac-7a1a370ad065.png)

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

# 画像のパスの読み込み

ちなみに画像のパスはヘッダで読み込まなくても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/>);
```

# 参考記事

https://qiita.com/hiro949/items/855e64ba7934d1774d91

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