見出し画像

Reactってそもそも何?【寺尾 美幸 / Misaki Terao】

皆様、こんにちは!エンジニアの寺尾と申します👩🏻‍💻🌷
Marvel入社から約1年、様々なイベントに関わらせていただきました。
今回はMarvel初のアドベントカレンダーの執筆ということで、Reactの基礎知識を共有させていただきます🎄

React初学者の方の参考になれば嬉しいです!

1.Reactの特徴

Reactは大きく分けて以下3つの特徴があります。

  • 世界で最も使用されているjavascriptライブラリ

  • 関数型プログラミング

  • JSXでの記述

それぞれの特徴を詳しく見ていきます!

1.世界で最も使用されているjavascriptライブラリ

ReactはFacebook社と有志により開発されたJSライブラリです。
VueやAngularといった主流のJSフレームワークと比較しても、最も利用ユーザー数の多いライブラリとなります。
※よく混同されますが、Reactはフレームワークではなくライブラリです。

Reactを使用して開発された有名なアプリとして、InstagramやUber Eatsなどが挙げられます。
表示速度を求められるWebアプリにおいて、Reactは存分に力を発揮できます。

また、AWSのAmplify StudioにもReactは採用されています。
これはFigmaデータをReactのUIに自動的に変換し、数時間でWebアプリを簡単に構築する便利なサービスです。
(AWS公式:https://aws.amazon.com/jp/amplify/studio/

さらにReactを学習すると、スマホアプリやデスクトップアプリの開発も行えます。
Webアプリ開発以外にも幅広く使えるので、習得して損はないライブラリです。

2.関数型プログラミング

Reactは関数型プログラミングと定義されます。
1行ずつ順に実行する手続き型プログラミングと違い、関数型プログラミングは動作を関数に分割します。

両者の記述方法の違いとして、配列[10, 20]を2倍にして返却する処理のイメージを記載します。

手続き型プログラミング

const nums = [10, 20];
let doubleNums = [];
for(let i = 0; i < nums.length; i++) {
  let double = nums[i] * 2;
  doubleNums.push(double);
}

関数型プログラミング

  const nums = [10, 20];
  const doubleNums = nums.map(num => num * 2)

上記はあくまで処理のイメージですが、関数型プログラミングの方がより簡潔に表記できることがお判りいただけたかと思います。

3.JSXでの記述

JSXという記法により、直感的にコーディングが行えます。
※JSXはReact用に開発されたJavaScriptの構文拡張で、他にも複数の Web フレームワークで利用されています。

例えば「Hello, JSX!」を表示させる例を見てみます。

const Hello = () => {
  return (
    <div>
      <h3>Hello, JSX!</h3>
    </div>
  );
};


export default Hello;

React初学者の方でも、上記のコードが何を表しているのか感覚的に分かるのではないでしょうか。

Reactは上記Helloのような部品(コンポーネント)を組み合わせて構築するのが特徴です。

ここで1つ問題です。

以下のようなWebアプリがあった場合、どれがコンポーネントに該当すると思いますか?






答えは全てです😳😳

レイアウトは省略していますが、上記は以下のように分割されていると考えてください。

const Main = () => {
  return (
    <>
      <Button />
      <Header />
      <Sidebar />
      <Contents>
        <ChildContents1 />
        <ChildContents2 />
        <ChildContents3 />
        <ChildContents4 />
      </Contents>
    </>
  );
};


const Button = () => {
  return (
    // ボタンコンポーネントを記述
  );
};


const Header = () => {
  return (
    // ヘッダーコンポーネントを記述
  );
};


const Sidebar = () => {
  return (
    // サイドバーコンポーネントを記述
  );
};


const Contents = () => {
  return (
    // コンテンツコンポーネントを記述
  );
};


const ChildContents1 = () => {
  return (
    // 小コンテンツコンポーネントを記述
  );
};
// 省略
const ChildContents4 = () => {
  return (
    // 小コンテンツコンポーネントを記述
  );
};

部品を組み立てて、一つの画面を作り上げるイメージが掴めたでしょうか?
また、作成したコンポーネントは別の画面でも再利用することができるため
全体的にコードの記述量もバグの発生も抑えることができます。
※特にボタンコンポーネントなどは再利用されやすいですね!
このような、部品を細かく分けて組み合わせる考え方をコンポーネント指向と呼びます。

コンポーネント指向は、部品さえ用意していればCSSが苦手な方でもフロントエンドの開発に参加しやすくなります。

以上、Reactの特徴でした!

2.Reactのステート管理とは

早速ですが、以下ソースコードを見てください。
inputに「Sample」と値を入力した後、valには何が入っているでしょうか?

const Example = () => {
  let val = "";


  return (
    <>
      <input
        type="text"
        onChange={(e) => { 
          val === e.target.value;
        }}
      />
    /* 以下valには何が入りますか? */
      {val}
    </>
  );
};


export default Example;



正解は空文字(初期値)となります。

Reactはコンポーネントを再実行(再レンダリング)しなければ、画面が変更されません。
今回の場合、Example全体を再実行しなければなりません。
ただし、変数valはコンポーネントの上部で初期化しているため、何度実行しても初期値(今回はundefined)となってしまいます。

では変更した値を保持したままコンポーネントを再実行するにはどうすれば良いでしょうか?

ReactにはuseStateという値を保持しておくための仕組みがあります。
※useStateはReact Hookと呼ばれるReactの便利機能の一つです。
 他にも様々な機能が提供されているため、興味のある方は以下をご覧になってください!
(公式リファレンス:https://ja.react.dev/reference/react/hooks

const [val, setVal] = useState(0);

※val:現在値、setVal:更新関数、useState(0):初期値

これはコンポーネントの再レンダリングのトリガーにもなります。
⇒つまり更新関数を使い、現在値を変更することで画面が再レンダリングされます。

useStateを使って先ほどのサンプルソースを書き換えると以下のようになります。

const Example = () => {
  const [val, setVal] = useState("");
  return (
    <>
      <input
        type="text"
        onChange={(e) => {
          setVal(e.target.value);
        }}
      />
/* 以下valに入力値が格納されます */
      {val}
    </>
  );
};


export default Example;

ただし、useStateの更新は即時でないことに注意してください。
更新関数で設定した値は、次のレンダリング時に変更する値を予約するものになります。

そのため以下の例だとconsole.logの中身は変更前の値が格納されています。
inputに「Sample」と入力しようとすると、Sの入力時は空文字、aの入力時にSが表示されるといった形になります。

const Example = () => {
  const [val, setVal] = useState("");
  return (
    <>
      <input
        type="text"
        onChange={(e) => {
          setVal(e.target.value);
    /* 以下valは変更前の値が格納されます。 */
	    console.log(val)
        }}
      />
      {val}
    </>
  );
};


export default Example;

またReactにはuseStateの他にuseRefという機能でも値を保持しておくことが可能です。
これは、再レンダリングされても値を保持するという点においてuseStateと同じですが、
useRefの値を変更しても再レンダリングがトリガーされないという特徴があります。
値を更新しても画面表示を再レンダリングさせたくない場合に便利です。

ただ、useRefは一般的にDOM要素へのアクセスに使われることが多いです。
簡単な使用例をご紹介します。
こちらはフォーカスと書かれたボタンを押下すると、input要素にフォーカスがあたるコードになります。
操作したい要素(今回はinput)のrefに作成したrefオブジェクトを渡し、ボタンのonClickイベントでメソッドを呼び出しております。

const Focus = () => {
  const [value, setValue] = useState("");
  const inputRef = useRef<HTMLInputElement>(null);


  return (
    <>
      <input
        type="text"
        ref={inputRef}
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
      <button onClick={() => inputRef.current?.focus()}>
        フォーカス
      </button>
    </>
  );
};

これを応用することで、別のコンポーネントの要素を操作することも可能です。
※ただし、場合によってはリスクが発生するため、使用する際はご注意ください。
(参考:https://ja.react.dev/learn/manipulating-the-dom-with-refs#best-practices-for-dom-manipulation-with-refs)

以上がReactのステートになります。

少しでもReactについて理解が深められましたでしょうか?😳
ただ今回紹介した知識だけでは、残念ながらWebアプリを作ることは難しいです☁️
Reactはライブラリのため、他のライブラリを追加してようやくWebアプリとしての形が出来上がります👀
学習コストがやや高いのも事実ですが、使いこなせれば非常に楽しいライブラリになります🔥🔥

この記事がきっかけとなり、皆様がReactに興味を持っていただければ幸甚です✨✨
最後までお読みいただきありがとうございました!😌🍀

Marvelでは今年『Marvelアドベントカレンダー2023』をやります🎄🎅Marvelのエンジニアがクリスマスまで記事のバトンを繋ぎます🔥
是非毎日のお楽しみとしてご覧ください😊
★Marvelのアドベントカレンダーはこちらhttps://adventar.org/calendars/9781


この記事が気に入ったらサポートをしてみませんか?