Reactのコードの書き方のお勉強

こんにちは。
株式会社クラスアクト インフラストラクチャ事業部の大塚です。

昨日Reactを使ったWebアプリの作成方法について初めて学びました。
今回は、その時に使用したコードを分解・精査しどういう書き方をするのか学んでいきたいと思います。
前回の記事は以下となります。

https://qiita.com/ohtsuka-shota/items/f3f69a1330e59430ead7

# コード
## App.js
```App.js
import React from 'react';
import './App.css';
import eyeIcon from './目のアイコン8.jpeg';
import addUserIcon from './contact_user_add_user_new_user_icon_250756.png';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      showPassword: false,
    };
  }

  handleSubmit = (event) => {
    event.preventDefault();

    const username = this.usernameInput.value.trim();
    const password = this.passwordInput.value.trim();

    if (username === '' || password === '') {
      alert('すべての必須フィールドに入力してください。');
    } else if (!/^[a-zA-Z]+$/.test(username) || !/^[a-zA-Z]+$/.test(password)) {
      alert('全ての項目は英字のみを含む必要があります。');
    }
  };

  togglePasswordVisibility = () => {
    this.setState((prevState) => ({
      showPassword: !prevState.showPassword,
    }));
  };

  render() {
    return (
      <form action="" method="post" className="sign-up-group" id="sign-up-form" onSubmit={this.handleSubmit}>
        <div id="sign-up-icon">
          <img src={addUserIcon} alt="Add User Icon" />
        </div>
        <h1 id="sign-up-title">Please Sign-up</h1>
        <div className="sign-up-form">
          <input
            type="text"
            id="username"
            autoComplete="on"
            placeholder="ユーザー名"
            className="sign-up-content"
            ref={(input) => (this.usernameInput = input)}
          />
        </div>
        <div className="sign-up-form">
          <div className="password-container">
            <input
              type={this.state.showPassword ? 'text' : 'password'}
              id="password"
              autoComplete="off"
              placeholder="パスワード"
              className="sign-up-content"
              ref={(input) => (this.passwordInput = input)}
            />
            <img
              id="show-password-icon"
              src={eyeIcon}
              alt="Show Password"
              onClick={this.togglePasswordVisibility}
              style={{ cursor: 'pointer' }}
            />
          </div>
        </div>
        <div id="submit-form">
          <button id="sign-up-button" type="submit">
            サインアップ
          </button>
        </div>
      </form>
    );
  }
}

export default App;
```

## コードについてあれこれ調べてみる
- import './App.css';
import eyeIcon from './目のアイコン8.jpeg';
import addUserIcon from './contact_user_add_user_new_user_icon_250756.png';
    - App.jsで使用するスタイルシートや画像などを呼び出している
    - 画像はimportのあとに命名している名前をJS内に記載することで使用することが出来る。コンポーネントの簡単な例な気がする。

- render(){ 
    return(); 
    }
Reactで用意されているものみたいで、コンポーネントが描写されるときにこれが呼び出され、JSX(JavaScript XML)を返すようです。
    - JSX：
    JavaScriptの拡張構文。
    JavaScriptのファイル内にHTMLのようなコードを記述できるようにするもの。
    - コンポーネント：
    UIを構築するための部品のこと
    Reactのアプリはコンポーネントを組み合わせて全体のUIを構築する
    コンポーネントはプロパティや状態を受け取り、これに基づいてUIを生成する
    コンポーネントは大きく2つ種類があるみたい。
        - 関数コンポーネント
            - JavaScript関数とほぼ同義
            - React Hookを使用できる
                - stateを持たせたり、ライフサイクルに応じた処理を実装できる。
                - React Hookを実装できるようになったことで、関数コンポーネントで書くのが主流となった？
        - クラスコンポーネント
            - 以前のReactの主流の書き方

https://ja.react.dev/
    


https://kinsta.com/jp/knowledgebase/what-is-jsx/ 

ただrenderについて、公式サイトを漁ってみるとバージョンアップで消されるっぽい？おい！ChatGPT！

https://ja.react.dev/reference/react-dom/render

代替としてcreateRootになるっぽい。

https://ja.react.dev/reference/react-dom/client/createRoot

- onSubmit={this.handleSubmit}
formがsubmitされたときに実装される関数を定義している。
今回はhandleSubmitという関数を呼び出すという定義をしている。
実際にWebブラウザに描写されるものでイメージをしてみると、以下のサインアップボタンを押下した時に呼び出される関数を定義しているイメージか？
![2023123101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/d145bb8f-c026-6012-7c90-1f847fc3366d.png)
onsubmitのほかにonclickもある。これはコード内にonClick={this.togglePasswordVisibility}という形で記載している。今回のコードの場合、アイコンが押されるとtogglePasswordVisibilityという関数が呼び出されるということになる。

- ref={(input) => (this.usernameInput = input)}
    - ref={(引数) => (変数 = 引数)}と解釈をする。
    - inputが引数、usernameInputが変数。
    - refについては以下を参照。"コンポーネントに情報を「記憶」させたいが、その情報が新しいレンダーをトリガしないようにしたい場合、ref を使うことができます。"とのこと。

https://ja.react.dev/learn/referencing-values-with-refs

- handleSubmit = (event) => {
    event.preventDefault();
    }
    - handleSubmitが関数名となる。これは任意。
    event.preventDefault();とすることでフォームが通常行うページのリロードやデータの送信を阻止することが出来る。

- this.setState((prevState) => ({
      showPassword: !prevState.showPassword,
    }));
    - this.setState(newState, [callback]);と解釈する。関数。
    - React コンポーネントの状態（state）を更新するためのメソッドで、状態を変更するために使用される。setState を呼び出すことで、Reactは再レンダリングをトリガーし、新しい状態でコンポーネントを再描画する。
    - prevState は、React コンポーネントの setState メソッドのコールバック関数内で使用できる変数であり、前回の状態（state）を参照するために利用されます。setState を呼び出すと、React は新しい状態にアップデートし、再レンダリングをトリガー。そのとき、コールバック関数内で prevState を使用することで、アップデート前の状態にアクセスできる。（ChatGPT談）
    - ここでいうshowPasswordはrender内のformのpasswordの部分で記載されている"type={this.state.showPassword ? 'text' : 'password'}"のthis.state.showPasswordで定義されているもの。!prevState.showPasswordはshowPasswordの状態を反転するよ！ということを示している様子。
        - showPasswordの最初の状態は、this.state = { showPassword: false, };という記載からpasswordが格納されている。
        - !prevState.showPasswordが呼び出されることで、それが反転。つまりtext状態となり再レンダリングされ、パスワードが表示されるようになるということらしい。

- class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      showPassword: false,
    };
    関数コンポーネント 
    render()
  }
  export default App;
    - class App extends React.Component
    React ライブラリを使用して作成された React コンポーネントを定義するためのクラスの宣言。
    - export default App; で、このコンポーネントクラスを他のファイルから利用できるようにエクスポートしている。