😽

バックエンドエンジニアがフロントエンド技術をキャッチアップしてみた

2024/07/24に公開

目標

  • バックエンドとフロントエンドの連携を実装できるように、フロントエンドの技術を勉強する。

勉強方針

  • 細かいフロントエンドの技術を勉強するというより、エッセンスとなる概念・考え方を勉強する。
  • 以下の順番で勉強する
    • JavaScriptの基本
    • モダンJavaScriptの基本
    • Reactの基本

Javascriptの基本

以下の教材で勉強
はじめてのJavaScriptプログラミング入門

Javascriptの基本文法など

基本文法

基本文法として以下を学習。
概ねバックエンド言語と基本文法と同じなので、時間をかけずにさっと学習

  • データ型、
  • 演算子
  • 条件分岐
  • 関数
  • 繰り返し

関数定義は書き方が複数存在するのが面白い。
備忘録として以下に記載

// (1) function命令(pythonでもよく見られる関数)
// 例題:四角形の面積を求める関数
function getRectangle(height, width) { //引数
  return height * width; // 戻り値
}
console.log(getRectangle(3, 5));

// (2) 関数リテラル(無名関数、匿名関数)
/*
関数名を定義しないため、無名関数や匿名関数と呼ばれる。
バックエンドでも、関数を変数に入れることあったなー
*/
// 例題:四角形の面積を求める関数
const getRectangle = function(height, width) {
  return height * width;
}

console.log(getRectangle(3, 5));

// (3)Functionコンストラクタ
// 括弧の中に、引数と関数の処理を両方含めるのは馴染みがなくて面白いな-。chatgptに聞いたらあまり使わないらしい。

// 例題:四角形の面積を求める関数
const getRectangle 
  = new Function('height', 'width', 'return height * width');

console.log(getRectangle(3, 5));

// (4) アロー関数 : 関数リテラルの省略記法
const getRectangle = (height, width) => {
  return height * width;
};
console.log(getRectangle(3, 5));

あとはコールバック関数
コールバック関数 = 「時間がかかる○○が終わったら、🔼🔼を実行する(主に非同期処理)」
コールバック関数が便利な点 = 「時間がかかる非同期処理のあとに実行したい処理を制御する。この処理は時間がかかる非同期処理にしたいが、この非同期処理の後にこの関数を実行したいなど」

// コールバック関数
function greeting(name) {
  console.log('Hello!' + name + '-san.');
}

function inputUserName(callback) {
  let name = prompt('あなたのお名前を入力してください!');
  callback(name);
}

inputUserName(greeting);

JSはシングルスレッド

  • Javascriptはシングルスレッド(一度に一つのタスクしか実行。タスクが直列に実行される)
    • ※マルチスレッド=複数のタスクを同時に実行、タスクを並行に複数処理できる

同期処理と非同期処理

  • 同期処理と非同期処理とは?
    • 同期処理:あるタスクが完了するまで次のタスクに進まない
      (重いタスクがあるとプログラムの実行が止まる)
    • 非同期処理 : タスクが開始された後、完了を待たずに次のタスクに進む処理


Proglearn JavaScriptの同期処理と非同期処理の違い|例え話を使って解説!の図を引用

  • Javascriptはシングルスレッドのため、非同期処理を使うことが重要(使わないと思い処理があると待ち時間が発生)

  • JavaScriptには元から非同期処理を行う関数がある。(setTimeoutなど)

  • JavaScriptには非同期処理をサポートするための機能があり、コールバック、Promise、async/awaitを使って非同期に処理を行うことができます。非同期処理を使うことで、長時間かかる操作を待たずに他の処理を進めることができます。

DOM

  • DOMはHTML等の文書をツリー構造で表現し、その各要素(Node)をJSで操作する

  • DOMの各要素(Node)を取得するには以下のような関数を用いる

const element = document.getElementById('example');
const elements = document.getElementsByClassName('example');
const elements = document.getElementsByTagName('div');
const element = document.querySelector('.example');

イベント処理

  • イベントとは?
    • システムの中で生じる動作や出来事など(例:ユーザーがボタンを押すなど)
  • イベントハンドラ
    • イベントに対して行われる処理(コンソールにhelloを出力するなど)
  • イベントリスナー
    • イベントやイベントハンドラを結びつける

// ボタン要素を取得
const button = document.getElementById('myButton');

// イベントハンドラを定義
function handleClick() {
    alert('Button was clicked!');
}

// イベントリスナーを追加
button.addEventListener('click', handleClick);

モダンJavascriptの技術

【最新ver対応済】モダンJavaScriptの基礎から始める挫折しないためのReact入門

  • 明確な定義はないが、以下のような技術が登場してからをモダンJSと呼ぶことが多い
    • ReactやVueなど仮想DOMを用いるフレームワークが登場
    • npm/yarnなどのパッケージマネージャー
    • ES2015以降の記法
    • WebpackやViteなどのモジュールバンドラー
    • Babelなどのトランスパイラ

仮想DOM

  • 仮想DOMが生まれた背景

    • これまでJSでDOMを直接操作してきたが、レンダリングコスト高(画面の表示スピードが遅い)/コードの複雑化。その問題を解決するために生まれたのが仮想DOM
  • 仮想DOMとは?

    • JSのオブジェクトで仮想的に作られたDOM : いきなりDOMを操作せずJS上で仮想DOMを操作し差分を出してからDOMに反映(開発者が仮想DOMを意識しなくてOK)

パッケージマネージャー

  • パッケージマネージャーが生まれた背景
    • それまでのJSはファイルを分割して、コードの再利用や共通化を図っていた。
    • しかし、分割したJSファイルを読み込む時に依存関係を意識しないとエラーが発生。
    • その問題を解決するのがパッケージマネージャー

モジュールバンドラー

  • モジュールバンドラーとは?

    • 複数のJSファイルを1つにまとめるツール(依存関係も考慮して1つにまとめてくれる)
  • モジュールバンドラーが生まれた背景

    • コードの保守性・拡張性の観点から開発時はコードを分割しているが、本番環境で実行時は分割する必要はない。(複数ファイルの読み込みによりパフォーマンスが落ちるので、本番時は一つにまとめた方が良い)

トランスパイラ

  • トランスパイラとは?
    • 新しいJSの記法-> 古いJSの記法に変換
  • トランスパイラが生まれた背景
    • 新しいJSの記法に対応していないブラウザのために開発時は新しい記法、実行する時は古い記法に変換する。

SPA

  • SPAとは?
    • HTMLは一つで、JSで画面を書き換える
  • SPAのメリット
    • ページ遷移のスピード上がる
    • コンポーネント分割により開発生産性が上がる

React

Reactの良さ

  • ピュアJS(=vanila JS)でアプリを開発すると、以下の問題が発生する。Reactで解決することができる。
    • DOMを取得して操作(=手続的)するため、コードが膨大になりがち。
    • Reactのコンポーネントを利用して、膨大なコード問題を軽減させる

JSX

  • JSXは、JavaScriptの構文拡張であり、最終的には通常のJavaScriptコードにコンパイルされる

コンポーネント

  • ReactアプリケーションのUIを構築するための再利用可能な部品

Props

  • コンポーネント間でデータを受け渡すための仕組み

State

  • Reactのstateは、コンポーネントの動的なデータを管理するための仕組みです。stateを使用すると、コンポーネントの表示や動作を動的に変更することができます。

  • ReactのStateの基本概念

    • 1.動的データの管理:
      • stateは、ユーザーの入力や外部データの取得などによって変わる可能性のあるデータを保持します。propsが親コンポーネントから渡される固定データであるのに対し、stateはコンポーネント内で変更されることを前提としています。
    • 2.初期化
      • stateは通常、コンポーネントの初期化時に設定されます。関数コンポーネントでは、useStateフックを使ってstateを初期化します。
    • 3.変更
      • stateは直接変更することはできず、setState(関数コンポーネントの場合はuseStateから返されるセッター関数)を使って変更します。この方法により、Reactは自動的に再レンダリングをトリガーして、最新のstateに基づいてUIを更新します。
// useStateのインポート:
import React, { useState } from 'react';

function Counter() {
  // useStateフックを使ってstateを初期化する
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
        // setCountのstateのcountを変える
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
export default Counter;

再レンダリング

  • Reactの再レンダリングとは、コンポーネントの状態やプロパティ(stateやprops)が変更されたときに、Reactがその変更を反映するためにコンポーネントを再描画するプロセスを指します。再レンダリングは、UIの一貫性を保ち、最新のデータを表示するために不可欠です。
const [count, setCount] = useState(0);

const increment = () => {
  setCount(count + 1); // countが変更されると再レンダリングされる
};

return (
  <div>
    <p>{count}</p>
    <button onClick={increment}>Increment</button>
  </div>
);

useEffect

  • Reactの再レンダリングで、stateの値が変わるたびに再レンダリングが走る。
  • useEffectで、特定のstateが変わった時のみに再レンダリングできる。
//このuseEffectは、countが変更されるたびに実行され、ドキュメントのタイトルを更新します。
//依存配列にcountを指定しているため、countが変わったときだけ副作用が再実行されます。
useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]);

感想

  • 自分の知識がモダンJavascriptより前ぐらいで止まっていたため、キャッチアップしてめちゃくちゃ役に立った。
  • バックエンドエンジニアだが、今後もフロントの知識を勉強していかないといけないなーとしみじみ感じました。
  • あとはTypeScriptやNext.jsのキャッチアップもしたい(時間作りたい。。汗)

Discussion