Reactを使いこなすための基礎学習

## アロー関数
```
function fn(number) {
  return number * 2;
}
```
上記をアロー関数に変換する

```
・引数の表示

引数が2つなら
const fn = (number1, number2,...) => {
  return number * 2;
}
引数が一つなら
const fn = number => {
  return number * 2;
}
```

```javascript
・関数ないの記述
関数記述が1行なら
const fn = number => return number * 2;

関数記述が２行なら
const fn = number => {
  console.log(2);
  return number * 2;
}

関数記述が1行でオブジェクトを返すなら
()で括る
const fn = number =>({result:number*2});
```

## ESモジュールについて

Javascriptのファイルを一つのモジュールという単位にして、このファイルごとに機能を管理する。
使う際にはexportして利用する

main.js
```javascript
import { hello } from "./module.js";
// モジュールバンドル（webpack)を使う際にはjs拡張子が補完されるが、
// htmlファイルについては、jsまで記載
import { User } from "./module.js";

// 同じファイルからであれば、1行にまとめることも可能(export)
import {hello,User } from "./module.js"

import funcB from "./module.js"
// default が一つしかないので、
//{}は不要
// 好きな名前を記載できる

//上記全て同じファイルの場合
import funcB, {hello,User} from "./module.js"


hello();

const user = new User('Tom');
user.hello();
// 

```
module.js
```javascript
export const hello = () => {
  console.log("hello!");
};

const funcB = () => {
  console.log("funcB output");
};

export default funcB;

class User {
  constructor(name) {
    this.name = name;
  }
  hello() {
    console.log(this.name);
  }
}

export { User }
// 外部からアクセスさせたくない関数を定義した場合には、先頭にexportせずに
```



index.html
```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>開始時点コード</title>
  </head>
  <body>
    <h1>開始時点コード</h1>
        <script type="module" src="main.js"></script>
        <!-- es moduleを使うにはtype moduleを使う必要がある -->
        <!-- reactではesモジュールのコードをjaavascriptに変換する処理が入っている。 -->
        <!-- 直接index.htmlから読み込む際には type="module"が必要-->
  </body>
</html>

```

## コールバック関数
コールバック関数とは引数に渡された関数を指す
```javascript
function print(callback) {
 const result = callback();//これ
 console.log(result);
}

function fn(number = 3) {
// 初期値として3を設定する。
// 初期値がないとコールバック関数を使った場合にはnumberがundefinedとして定義される。
 return number * 2;
  }

debugger;
// デバッガーにてコンソールにてフローが確認可能
print(fn);
// ここでは引数numberがなし(undefined)のため、結果としてNaNとなる。
```

## DOMとイベントリスナーについて
 DOMとはHTMLのタグをJSから操作するときに使用するもの
```javascript
const h1Element = document.querySelector('h1');

console.log(h1Element);
console.dir(h1Element);
// DOMオブジェクトの実態
// プロパティの形式

console.log(h1Element.textContent);
h1Element.textContent = "変更後のタイトル"
// オブジェクトの形式でHTMLにアクセスする
// ノード、エレメントとも呼ぶ

const btnEl = document.querySelector('button');



//イベントリスナーに設定されている場合
btnEl.addEventListener('click', (e) => {
 // 第一引数：イベント名
 // 第２引数：実行する関数（コールバック関数）

 console.dir(e.target.text);
 // e:イベントのオブジェクト
 // 発火に伴うオブジェクトが参照可能 .dir
 console.log('hello');
})




// 関数を別に定義した場合

const fn = (e) => {
// fnを下記にてコールバック関数として定義
// eは関数が実行されるときにセットされて渡される。
 console.dir(e.target.text);
 // e:イベントのオブジェクト
 // 発火に伴うオブジェクト
 console.log('hello');
}
btnEl.addEventListener('click', fn);
// fnが実行可能な状態になる。

```

## 配列のmap,filter
for文などを使うことによって記述量が長くなり、ごちゃごちゃしてしまうため、
map,filterを使うことにより、記述量を減らし可読性をあげることができる。

```javascript
const arry = [10, 20, 30, 40];
const newArry = [];


for (let i = 0; i < arry.length; i++){

 newArry.push(arry[i]*2)
}

console.log(newArry)

// 上記をmapメソッドで

const newArry2 = arry.map(val => {
 console.log(val)
 // arryの値が順番に格納されている。
 return val * 3;
});

console.log(newArry2);


const newArry3 = arry.map((val, i, arry) => {
 // (val,i,arry):実際に定義できる
 console.log(val)
 return val * 3;
});


// filterメソッド

for (let i = 0; i < arry.length; i++){
 const val = arry[i] * 2;
 if (val > 50) {
  newArry.push(arry[i]*2)
 }
}

const newArry4 = newArry2.filter(val => {
 return val > 50
});
// コールバックする関数がリターンする値がtrueであれば条件が追加される
console.log(newArry4)


// filtrとマップを一緒に使う場合には
const newArry5 = arry.map(val => val * 2).filter(val => val > 50);

console.log(newArry5)
```

## 分割代入
 分割代入というのは、配列やオブジェクトの特定の要素を変数として抽出する


```javascript

const arry = ["配列1", "配列2", "配列3"];
console.log(arry[0]);
console.log(arry[2]);


const [a, b, c] = ["配列1", "配列2", "配列3"];
// 下記のように取り出したい部分だけ定義でもOK
const [d,  , e] = ["配列1", "配列2", "配列3"];
const [d] = ["配列1", "配列2", "配列3"];
console.log(a);
console.log(b);

const obj = { x: "オブジェクト1", y: "オブジェクト2", z: "オブジェクト3" };
console.log(obj.x);
console.log(obj.y);

const {x,z} = { x: "オブジェクト1", y: "オブジェクト2", z: "オブジェクト3" };
// const {z,x}〜としても、オブジェクトの分割代入はプロパティ名と一致させる必要がある。
console.log(x);
console.log(z);

const arr = ["Japan", "Tokyo", "Shinjuku"];
const objAddress = { state: "Tokyo", country: "Japan",  city: "Shinjuku" };

const fnArr = (arry) => {
  console.log("---配列---");
  console.log(`country: ${arry[0]}`);
  console.log(`state: ${arry[1]}`);
  console.log(`city: ${arry[2]}`);
};
const fnArr2 = ([country, state, city]) => {
 // 配列は順番に気をつける
  console.log("---配列---");
  console.log(`country: ${country}`);
  console.log(`state: ${state}`);
  console.log(`city: ${city}`);
};

const fnObj = (objAddr) => {
  console.log("---オブジェクト---");
 console.log(`country: ${objAddr.country}`);
  console.log(`state: ${objAddr.state}`);
  console.log(`city: ${objAddr.city}`);
};

// 分割代入パターン
const fnObj2 = ({country,state,city}) => {
  console.log("---オブジェクト---");
  console.log(`country: ${country}`);
  console.log(`state: ${state}`);
  console.log(`city: ${city}`);
};

fnArr(arr);
fnObj(objAddress);
```


## スプレッド演算子、レストパラメータ
スプレッドを使う場合には、使わない場合に比べて意味合いが変わるので注意する。
スプレッドの場合には、あくまで新規配列に要素を展開するために内容が異なる。

```javascript
const nums = [3, 1, 4, 1, 5, 10, 2, 6];

const result = Math.max(3, 1, 4, 1, 5, 10, 2, 6);
// スプレッドを使う場合には、使わない場合に比べて意味合いが変わるので注意する。

// スプレッド演算子を利用した場合
// 配列の要素を展開する場合
const result2 = Math.max(...nums);
console.log(result);


let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let newArr = [...arr1];// 要素が展開されて、新しい配列となる。
console.log(newArr);
// スプレッド演算子で展開した場合、等価演算子で確認するとfalseになる。>別物
console.log(newArr === arr1);
newArr.push(5);
// 参照先が異なるので、
console.log(newArr, arr1)


let newArr1 = arr1
// 通常代入した場合で展開した場合、等価演算子で確認するとtureになる。
console.log(newArr1 === arr1)
// 代入した場合には参照している配列が同じ
// 通常代入はあくまで参照先を同じにしている。
newArr1.push(4);
console.log(newArr1,arr1)


let newArr3 = [...arr1, 10, ...arr2];// 要素が展開されて、新しい配列となる。

console.log(newArr3);





const obj = {
  name: "Tom",
  age: 22,
};
const newObj = { ...obj };
newObj.name = 'John';

console.log(newObj);
console.log(obj);
// スプレッド演算子を用いた場合には元の配列に影響を及ぼさない。


// レストパラメータ、残よ引数:(...argA)
// 可変数の引数に利用する場合
const restA = (...argA) => console.log(argA);
restA(1, 5, 4)

const restB = (n, ...argB) => console.log(argB,n);
restB(1, 3, 4)
```

## 三項演算子

条件変数 ? trueの場合 : falseの場合

```javascript
// 三項演算子（ ? : ）

const a = false;

let resultA = a ? "true": -10;
// 条件変数/ trueの場合/falseの場合
console.log(resultA);
if(a) {
  resultA = "true";
} else {
  resultA = "false";
}
console.log(resultA);

function getResult() {
  return a ? "true" : "false";
}

console.log(getResult());

```



## truthy falthy 論理話　論理積


```javascript
// falsy → 真偽値に変換した際に"偽(false)"とみなされる値のこと。
// truthy → それ以外

/* falsyな値の一覧
false
0 (数字)
0n (big int)
"" (空文字)
null
undefined
NaN (Not a Number)
*/

const a = 0;
let result = a ? 10 : -10;
console.log(result);

const falsy = 0;
const truthy = 1;
// 確認する手段
console.log(Boolean(truthy));
console.log(Boolean(falsy));

// 論理積 (&&) について
const resultA = "" && "foo"; //""が格納
const resultB = 2 && 1 && 0 && 3; //0を返す
const resultC = "foo" && 4;　//4（右側を返す)

// console.log(resultA);
console.log(resultB);
console.log(resultC);

// 理論和 (||) について
const resultD = "" || "foo";
const resultE = 0 || 2 || 0; //truthyが見つかったものを返す(2)
const resultF = "foo" || 4; //truthyが見つかったものを返す(foo)

console.log(resultD);
console.log(resultE);
console.log(resultF);

```

## 非同期処理　Promise
非同期処理が終わった後に特定の処理をつなげるときに使うのがPromise
```javascript
let a = 0;

console.log(a);


new Promise((resolve, reject) => {
 // 引数には上記2つの関数が渡る。
 setTimeout(() => {
  a = 2;
  resolve(a);
  reject(a);//エラー時に使う
  // 順番通りに動かない：非同期処理
 }, 2000);
}).then((b) => {
 // resolve()が呼ばれるとthenが実行される。
 console.log(b);
 return b;
 // returnで返す値が次のthenへ
}).then((b) => {
 // resolve()が呼ばれるとthenが実行される。
 console.log(b+1);
}).catch((a) => {
 // rejectが呼ばれるとcatchが実行される。
 // エラー時につながる
  console.log('error')
})



setTimeout(() => {
 a = 1;
 console.log(a)
 // 順番通りに動かない：非同期処理
}, 3000);

```


## await async


```javascript
// 非同期処理（Promise）
let a = 0;


// thenメソッドを使わないので便利になる
init();

async function init() {//awaitの使った関数の先頭にasyncをつける

 // 例外処理
 try {
   const result = await new Promise((resolve, reject) => {
  // resolveが呼ばれるまでこのawaitで書いた行で処理が待機するので終わり次第、次の行へ

    setTimeout(() => {
        a = 2;
        reject(a)
        // resolve(a)
    }, 2000);
 })
 } catch (e) {
  // 慣例的にeで引数が渡される。
  console.log('catchが実行',e)
 }

 console.log(result);
}
```