はじめに
Reactでよく使われるJavaScriptの記法についてまとめました。(前回の続きです。)
主に参考にしたのは以下の講座です。
【2023年最新】React(v18)完全入門ガイド|Hooks、Next.js、Redux、TypeScript
e.preventDefault()
参考資料
【JavaScript】event.preventDefault()が何をするのか - Qiita
submitイベントの発生元であるフォームが持つデフォルトの動作をキャンセルするメソッド
フォームが持つデフォルトの動作
:フォームの内容を指定したURLへ送信するという動作
※actionのところを省略すると、現在開いているページにリクエストを送信して、再度そのページでリロードされる
分割代入
参考資料
【初学者向け】JavaScriptの分割代入について - Qiita
配列やオブジェクトから値を取り出して、変数に代入してくれるJavaScriptの機能
通常の代入では一つの変数に対して一つの値を代入していくのに対して、分割代入は複数の変数に、配列やオブジェクトの値を一度に設定する
①配列の場合
左辺の変数は [ ] で囲う
const arry = [10, 20, 30];
//分割代入
const [a, b, c] = arry;
//確認
console.log(a); // 10
console.log(b); // 20
console.log(c); // 30
②オブジェクトの場合
左辺の変数は { } で囲う
変数名とプロパティは一致させる必要がある
//オブジェクトを作成
const obj = {
name: "Tom",
age: 87
}
//分割代入
const {name, age} = obj;
//確認
console.log(name); //Tom
console.log(age); //87
スプレッド構文(Spread Syntax)
...XXXの形で記述され、配列やオブジェクトの要素を文字通り展開する構文。
Array.prototype.concat()相当のことが簡潔にかける。
①配列の場合
const foo = [1, 2];
// 配列のクローン
const bar = [...foo]; // => [1, 2]
// 要素を追加して新しい配列を生成
const baz = [...foo, 3, 4]; // => [1, 2, 3, 4]
// 配列をマージ
const hoge = [...foo, ...bar]; // => [1, 2, 1, 2]
②オブジェクトの場合
const foo = { a: 1, b: 2 };
// オブジェクトのクローン
const bar = { ...foo }; // => { a: 1, b: 2 }
// プロパティを追加した新しいオブジェクトの生成
const baz = { ...foo, c: 3 }; // => { a: 1, b: 2, c: 3 }
// オブジェクトのマージ
const hoge = { ...foo, ...{ c: 3, d: 4 } }; // => { a: 1, b: 2, c: 3, d: 4 }
// 元のオブジェクトに同名プロパティがある場合は置き換わる
const fuga = { ...foo, b: 3 }; // => { a: 1, b: 3 }
const piyo = { ...foo, ...{ a: 3, b: 4 } }; // => { a: 3, b: 4 }
残余引数
参考資料
スプレッド構文と残余引数について【備忘録】 #JavaScript - Qiita
実行時に渡される引数の数がわからない場合に、
実際に引数として渡された複数の値を配列としてまとめて「残余引数」に格納することができる
function sample2(firstItem, ...restItem) {
console.log(firstItem);
console.log(restItem);
}
sample2('緑茶', '抹茶', 'チャイ', 'ココア');
/* 実行結果
緑茶
['抹茶', 'チャイ', 'ココア']
三項演算子
参考資料
【初学者向け】JavaScriptの三項演算子『?』について #JavaScript - Qiita
- if文の場合
if (条件式) {
trueの場合の処理
} else {
falseの場合の処理
}
条件式が
trueなら→trueの場合の処理を実行
falseなら→falseの場合の処理を実行
- 三項演算子の場合
条件式 ? trueの場合の処理 : falseの場合の処理;
条件式の後に「?」を記述
→trueなら直後のtrueの場合の処理を実行
→falseなら「:」の後のfalseの場合の処理を実行
Null合体演算子
参考資料
【JavaScript】Null合体演算子と(??)とオプショナルチェイニング演算子(?.) - Qiita
A ?? B
演算子の一種で左辺がnullまたはundefinedのときに右辺の値を返し、それ以外のときには左辺を返す。
falsyな値とtruthyな値
参考資料
[ JavaScript入門 ] falsyな値とtruthyな値とはなんなのか?またどのような時に使用するのか。 - Qiita
-
falsyな値
Booleanで真偽値に変換した場合にfalseになる値のこと。 (例:false,null,0,undefined.0n,NaN) -
truthyな値
falsyな値以外
Promise
参考資料
【JavaScript】 非同期はPromise?解説が難しいので自分で理解してみた (affi-sapo-sv.com)
【ES6】 JavaScript初心者でもわかるPromise講座 - Qiita
PromiseとAsync/Awaitについて - Qiita
JavaScriptのPromiseを理解する - Qiita
処理の順序(処理を待機することや、その結果に応じて次の処理をすること)を約束するもの
PromiseStatusという3つの状態がある
・pending: 未解決 (処理が終わるのを待っている状態)
・resolved: 解決済み (処理が終わり、無事成功した状態)
・rejected: 拒否 (処理が失敗に終わってしまった状態)
<基本的な書き方>
new Promise((resolve,reject) => {
// 同期処理
resolve() // もしくは reject()
})
.then(() => {
// 非同期処理(resolveを待つ)
})
.catch(() => {
// 非同期処理(rejectを待つ)
})
.finally(() => {
// 非同期処理(then、またはcatchを待つ)
});
new Promiseの引数に与えたコールバック関数は同期処理される。
thenメソッドやcatchメソッド、finallyメソッドは全て非同期で実行される。
resolveが呼ばれた場合は、thenメソッドの中のコールバック関数が実行され、このコールバック関数の引数にはresolveで渡した実引数が渡る。
thenメソッドが完了すると、catchメソッドはスキップされ、finallyメソッドに処理が移る。
const Test = () => {
console.log("1番目");
// 約束を取り付けたい処理にPromiseを使う
new Promise((resolve) => {
//1秒後に実行する処理
setTimeout(() => {
console.log("2番目(1秒後に実行)");
//無事処理が終わったことを伝える
resolve();
}, 1000);
}).then(() => {
// 処理が無事終わったことを受けとって実行される処理
console.log("3番目");
});
return (
<p>テスト</p>
)
};
function App2() {
return (
<>
<Test />
</>
);
}
resolve関数
戻り値:Promiseオブジェクトを返す
この戻り値を次に呼ばれるメソッド(then)の第一引数に渡すことが出来る。
const promise = new Promise((resolve) => {
// 引数に文字列を渡す
resolve("resolveしたよ");
}).then((val) => {
// 第一引数にて、resolve関数で渡した文字列を受け取ることができる
console.log(val);
});
Promise.all
配列でPromiseオブジェクトを渡し、全てのPromiseオブジェクトがresolvedになったら次の処理に進む。
Promise.all([非同期処理1, 非同期処理2, ...])
.then((result) => {
// 全ての非同期処理が成功した
})
.catch((result) => {
// いづれかの非同期処理が失敗した
});
const Test = () => {
const promise1 = new Promise((resolve) => {
setTimeout(() => {
resolve();
}, 1000);
}).then(() => {
console.log("promise1おわったよ!");
return ("promise1戻り値");
});
const promise2 = new Promise((resolve) => {
setTimeout(() => {
resolve();
}, 3000);
}).then(() => {
console.log("promise2おわったよ!");
return ("promise2戻り値");
});
Promise.all([promise1, promise2])
.then((val) => {
console.log("引数val :" + val);
console.log("全部おわったよ!");
});
return (
<p>テスト</p>
)
};
function AppTest() {
return (
<>
<Test />
</>
);
}
export default AppTest;
new PromiseとPromise.resolveの違い
参考資料
new PromiseとPromise.resolveの違い - Qiita
<正常処理の場合>
function fn() {
return 'Hello';
}
var ret1 = new Promise(function (resolve) {
resolve(fn());
});
console.log(ret1);
var ret2 = Promise.resolve(fn());
console.log(ret2);
実行結果はどちらも 'Hello' でresolveされた Promise オブジェクトが返って来る。
<例外が発生する場合>
function fn() {
//例外を発生させる
throw new Error('BAAD');
}
var ret1 = new Promise(function (resolve) {
resolve(fn());
});
// 例外発生時はrejectされた Promise オブジェクトが返される
console.log(ret1);
var ret2 = Promise.resolve(fn());
console.log(ret2);
new Promiseだと、コンストラクタ内で渡された関数を try{} で例外処理して呼び出し、
例外発生時はrejectされた Promise オブジェクトを返す。
Promise.resolveだと、 Promise.resolveの呼び出し前に例外がトップレベルで発生し、プログラムが終了する。
そのためret1の結果のみ返ってくる。
setTimeout
参考資料
awaitできるsetTimeoutを1行で書く方法 - Qiita
☆以下のように省略して記載できる。
例)3000ミリ秒待機するという処理。すべて同じ実行結果となる。
<基本的な長めの書き方>
const sleep = () => new Promise(resolve => {
setTimeout(() => {
resolve()
}, 3000)
})
await sleep()
<省略系>
// 1: () => { resolve() } は resolve に短縮する
const sleep = () => new Promise(resolve => {
setTimeout(resolve, 3000)
})
await sleep()
// 2: resolve => {} は resolve => に短縮する
const sleep = () => new Promise(resolve => setTimeout(resolve, 3000))
const promise = sleep()
await promise
// 3: sleep()は関数でなくていいので値にする
const promise = new Promise(resolve => setTimeout(resolve, 3000))
await promise
// 4: 完成
await new Promise(resolve => setTimeout(resolve, 3000))