JavaScriptについてまとめた

「モダンJavaScriptの基礎から始める挫折しないためのReact入門」を学習した内容をまとめる 

#### JavaScriptの用語
##### DOM
- DOMとは、Document Object Modelの略。ドムと読む。HTMLなどを解釈し、木構造で表現したもの。
→レンダリングコスト高、コードの複雑化
DOMの欠点を解決する為に作られたのが仮想DOM

- 仮想DOMとは、いきなりDOMを操作せず、JS上で仮想DOMを操作し差分を出してからDOMに反映。

##### パッケージマネージャー
- かつてのJavaScriptは1つのJSファイルにすべての処理を記載していた。
→処理が複雑になるにつれてコードがカオス化、コードの再利用ができない

- ちょっと改善されたJavaScript
他のJSファイルを読み込んで使っていた。
→コードの再利用、共通化はできるようになった、読込順を意識しないとエラーになる、何がどこから読み込まれたものかわからない。

- 試行錯誤があり、モダンJavaScript
npm.yarnなどのパッケージマネージャを使用
→内部ではNode.jsが動いている。
依存関係を勝手に解決してくれる、import先が明示的にわかる、世界中で硬化されているパッケージをコマンド1つで利用可能、チーム内での共有も簡単

##### ES2015
ESとはECMAScript(えくますくりぷと)
JavaScriptの標準規格(こういうルールで書いてね！)
欧州電子計算機工業会(ECMA：European Computer Manufactures Association)
年に1回発表される。
ES5=ES2014、ES6=ES2015、、
ES2015で機能追加が多くあり、近代JSの転換期( let, const アローファンクション,class構文など)

##### モジュールバンドラー
モジュールバンドラーとは、複数のjs(css/image)ファイルを1つにまとめる為のもの。
webpackなどがある。

##### トランスパイラ(BABEL)とは
トランスパイラとは、新しいJavaScriptの記法を古い記法に変換してくれる。
BABELなどがある。

##### SPA(Single Page Application)
モダンJavaScriptはSPAが基本。
HTMLは1つのみでJavaScriptで画面を書き換える。

- メリット
ページ遷移事のちらつきがなくなる
表示速度のアップによるユーザー体験向上
コンポーネント分割が容易になることでの開発効率アップ

#### JavaScriptの基礎構文
##### アロー関数
「=>(矢)」を使って関数を記述する。
```javascript:sample.js

//アロー関数
(引数,...)=>{...関数の本体...}

const func3 = (num1, num2) => {
  return num1 + num2;
};

console.log(func3(10, 20));    //30
```

##### 分割代入
```javascript:sample.js
const myProfile = {
   name: "Mike",
   age: 20,
 };
const message1 = `私の名前は${myProfile.name}です。年齢は${myProfile.age}です。`;
console.log(message1);

const { name, age } = myProfile;    //分割代入
const message2 = `私の名前は${name}です。年齢は${age}です。`;
console.log(message2);
```

##### スプレッド構文
```javascript:sample.js
//配列の展開
const arr1 = [1, 2];
console.log(arr1);    //[1, 2]
console.log(...arr1);    //1 2

//まとめる
const arr2 = [1, 2, 3, 4, 5];
const [num1, num2, ...arr3] = arr2;
console.log(num1);    //1
console.log(num2);    //2
console.log(arr3);    //[3, 4, 5]
```

##### 論理演算子の本当の意味(&&, ||)
```javascript:sample.js
 const flag1 = true;
 const flag2 = false;

 if (flag1 || flag2) {
   console.log("1か2はtrueになります");    //1か2はtrueになります
 }

 if (flag1 && flag2) {
  console.log("1も2はtrueになります");    //
}

 //||は左側がfalseなら右側を返す
const num = null;
const fee = num || "金額未設定です";
console.log(fee);    //金額未設定です

 //&&は左側がtureなら右側を返す
const num2 = 100;
const fee2 = num2 && "何か設定されました";
console.log(fee2);    //何か設定されました

```

#### React
##### React
ReactはJavaScriptライブラリである。
index.htmlに記載されているidをReact(jsx)でレンダリングする構成をしている。

```html:index.html
<!DOCTYPE html>
<html lang="en">
    <head>
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    	<meta name="theme-color" content="#000000">
    	<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    	<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    	<title>React App</title>
    </head>
    <body>
    	<div id="root"></div>
    </body>
</html>

```

```react:App.jsx
import React from "react";
import ReactDOM from "react-dom";

const App = () => {
  return (    //returnの中身が1つ以上のタグになる場合は、()で囲う。
    <>    //returnの中身は1つのタグで表現する必要がある。
      <h1>こんにちは</h1>
      <p>こんばんわ</p>
    </>    //<div></div>, <React.Fragment></React.Fragment>, <></>のいずれか
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
```

##### コンポーネント

画面要素の1単位。大(1画面)から小(1つのテキストボックス)まで様々である。
コンポーネントの命名規則として、パスカルケースを用いる。

```react:sample.jsx
//正しい例
App
SomeComponent

//エラーとなる例//
app
someComponent

//エラーにはならないが推奨されない例
Some_component
Some_Component
```

##### Props
Propsとはコンポーネントに渡す引数の様なもの。

```react:App.jsx
import React, from "react";
import { ColorfulMessage } from "./components/ColorfulMessage";

const App = () => {
  return (
    <>
      <h1 style={{ color: "red" }}>こんにちは</h1>
      <ColorfulMessage color="blue">お元気ですか</ColorfulMessage>
    </>
  );
};

export default App;
```

```React:ColorfulMessage.jsx
import React from "react";

export const ColorfulMessage = (props) => {
  const { color, children } = props;
  const contentStyle = {
    color: color,
    fontSize: "18px"
  };

  return <p style={contentStyle}>{children}</p>;
};

```

##### StateとEffect
- State
各コンポーネントが持つ状態。Stateが変更されると再レンダリングされる。
Stateは[ 変数, Set変数 ]にuseStateを代入する形式で宣言する。

- Effect
複数Stateがある時に、全てレンダリングするのではなく、特定のStateのみレンダリングしたい場合に使用する。

```react:
/*
*　数字が3の倍数の時に、絵文字を表示する。
*/
import React, { useEffect, useState } from "react";
import { ColorfulMessage } from "./components/ColorfulMessage";

const App = () => {
  const [num, setNum] = useState(0);    //useStateの()内には、初期値を入れる
  const [faceShowFlag, setFaceShowFlag] = useState(true);

  const onClickCountUp = () => {
    setNum(num + 1);
  };

  const onClickSwitchShowFlag = () => {
    setFaceShowFlag(!faceShowFlag);
  };

  useEffect(() => {
    if (num > 0) {
      if (num % 3 === 0) {
        faceShowFlag || setFaceShowFlag(true);
      } else {
        faceShowFlag && setFaceShowFlag(false);
      }
    }
  }, [num]);

  return (
    <>
      <button onClick={onClickCountUp}>カウントアップ</button>
      <button onClick={onClickSwitchShowFlag}>顔文字</button>
      <p>{num}</p>
      {faceShowFlag && <p>"(-""-)"</p>}
    </>
  );
};

```

##### 再レンダリングが起きる条件
・stateが更新されたコンポーネントは再レンダリング
・propsが変更されたコンポーネントは再レンダリング
・再レンダリングされたコンポーネント配下の子要素は再レンダリング

##### react router
react routerとは、画面間遷移を実現する為に用いる。
現在v6にアップデートされており、v5からv6にバージョンアップ時に下記の様にいくつか仕様変更されている。

```text
v5からv6の変化点
- useParams の型の変更に対応
- <NavLink /> の型の変更に対応
- <Switch /> を <Routes /> に変更
- <Route /> の型の変更に対応
- <Redirect /> を <Navigate /> に変更
- useHistory を useNavigate に変更
- useRouteMatch を useMatch に変更
```

URL、クエリパラメータを受け取り、画面遷移することが出来る。

##### AtomicDesign
AtomicDesignとは、BradFrost氏が考案したデザインシステム
画面要素を5段階に分け、組み合わせることでUIを実現
コンポーネント化された要素が画面を構成しているという考え方
React,Vue用というわけではない
モダンJavaScriptとの相性が良い

##### 5段階のコンポーネント
- Atomic：原子。
  最も小さくそれ以上分解できない要素。Twitterを例に挙げると、ボタン・ツイート入力テキストボックス・アイコン等
- Molecules：分子。
  Atomの組み合わせで意味を持つデザインパーツ。Twitterを例に挙げると、アイコン＋メニュー名・プロフィール画像＋テキストボックス・アイコンセット等
- Organisms：有機物。
  AtomやMoleculeの組み合わせで構成される単体である程度の意味をもつ要素群。Twitterを例に挙げると、ツイート入力エリア・サイドメニュー・1つのツイートエリア
- Templates：テンプレート。
　ページのレイアウトのみを表現する要素(実際のデータはもたない)Twitterを例に挙げると、サイドメニュー・ツイートエリア・トピックエリア等のレイアウト情報など
- Pages：最終的に表示される1画面。
  Twitterを例に挙げると、ページ遷移事に表示される各画面。

AtomicDesignに取り込む時のポイント
・まくまでベース：AtomicDesignはあくまで概念だと認識し、プロジェクトやチームに合わせてカスタマイズしていく
・初めから分けない：慣れない内に無理にコンポーネントに分けようとするとしんどい。まずは書いて定期的にリファクタリング
要素の関心を意識：「何に関心があるコンポーネントなのか」を意識しながら分割したりpropsを定義したりする

##### axios
axiosを使用してJSONPlaceholderからダミーデータを取得。
データの取得方法を学習
```react:axios.js
import axios from "axios";
import "./styles.css";

export default function App() {
  //ボタンが押されたら、JSONPlaceholderからusersのデータを取得
  const onClickUsers = () => {
    axios
      .get("https://jsonplaceholder.typicode.com/users")
      .then((res) => {
        console.log(res.data);
      })
      .catch((err) => console.log(err));
  };
  //ボタンが押されたら、JSONPlaceholderからusers1のデータを取得
  const onClickUser1 = () => {
    axios
      .get("https://jsonplaceholder.typicode.com/users/1")
      .then((res) => {
        console.log(res.data);
      })
      .catch((err) => console.log(err));
  };

  return (
    <div className="App">
      <button onClick={onClickUsers}>user</button>
      <button onClick={onClickUser1}>id=1</button>
    </div>
  );
}
```