「モダン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の基礎構文
アロー関数
「=>(矢)」を使って関数を記述する。
//アロー関数
(引数,...)=>{...関数の本体...}
const func3 = (num1, num2) => {
return num1 + num2;
};
console.log(func3(10, 20)); //30
分割代入
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);
スプレッド構文
//配列の展開
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]
論理演算子の本当の意味(&&, ||)
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)でレンダリングする構成をしている。
<!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>
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つのテキストボックス)まで様々である。
コンポーネントの命名規則として、パスカルケースを用いる。
//正しい例
App
SomeComponent
//エラーとなる例//
app
someComponent
//エラーにはならないが推奨されない例
Some_component
Some_Component
Props
Propsとはコンポーネントに渡す引数の様なもの。
import React, from "react";
import { ColorfulMessage } from "./components/ColorfulMessage";
const App = () => {
return (
<>
<h1 style={{ color: "red" }}>こんにちは</h1>
<ColorfulMessage color="blue">お元気ですか</ColorfulMessage>
</>
);
};
export default App;
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のみレンダリングしたい場合に使用する。
/*
* 数字が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にバージョンアップ時に下記の様にいくつか仕様変更されている。
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からダミーデータを取得。
データの取得方法を学習
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>
);
}