新卒入社3ヶ月でモダン開発プロジェクトに取り組んだ2024年を振り返る

## はじめに

筆者は、2024 年 4 月に株式会社ニジボックスに新卒で入社し、3 ヶ月ほど研修を受け、7 月から現在のモダンなフロントエンド技術を使用したプロジェクトにアサインされました。
入社時は、フロントエンドの実務経験ゼロの状態でした。大学では講義で Python を触るなどはしていました。また単純な LP を作成したことがあるくらいでした。

新卒で技術力もなく右も左もわからなかった私が、最低限業務を進められるようになるまでに 5 ヶ月間で取り組んで

- 良かったこと
- 悪かったこと

を振り返ります。

:::note info
主に技術的な話よりもマインド面の話が中心になっています
:::

### 対象読者

- フロントエンド初心者、実務経験があまりない人
- これからモダンなプロジェクトにはじめて取り組む人

### 使用技術 (すべて使ったことがありませんでした)

とくに個別で触れるわけではないですが、アサインされたプロジェクトのフロントエンド領域では以下の技術を採用しています。

- TypeScript
- Next.js
- React Hook Form
- Zod
- Jest
- React Testing Library
- MSW (Mock Service Worker)
- Storybook

## プロジェクトで何ができなかったのか？

### 大前提

アサインされたプロジェクトにはチュートリアルが用意されており、自分のペースで上記の技術を使いながらキャッチアップする時間が 1 か月ほどありました。
その期間で、プロジェクトのお作法であったり、基礎基本の知識を身に着けました。最低限の力をつけたうえで、実務に入っていってできなかったことがメインになります。

### できなかったこと

私が実際にできなかったり、理解に時間がかかったことは以下の通りです。
このそれぞれについて、やってみてよかったこと、悪かったことを振り返っていこうと思います！

- **コードが読めなかった**
- **コードが書けなかった**
- **質問ができなかった**

## 実践してみて良かったこと、悪かったこと

### コードが読めなかった

最初は本当に、コードが読めず、ただの文字列をぼーっと眺めるような感じでした。
最近になってようやく少しずつ読めるようになりました

#### 悪かったこと

##### とにかく、１つ１つの処理を追おうとしていた

もちろん大事ですが、そもそも全体像として何をやりたいか？があまり理解できないまま、コードを読んでいました。
以下は生成したサンプルコードです。自分は以下のコードを読むとき、1 行ずつ読んでいき、formatUserBirthday 関数を見つけると、cmd+クリックで内部の実装まで参照してしまっていました。その内部処理で難しい処理があると、詰まって検索し、理解できた時には何をしていたのか本質を見失ってしまっていました・・・

```tsx
import React from 'react';
import { formatUserBirthday, displayUserAddress } from '../utils/formatters';

const UserInfoCard = ({ userData }) => {
  if (!userData) {
    return <div>Loading user data...</div>;
  }
    // NG 全体の流れを把握する前に関数の内部処理を追ってしまう
    const formattedBirthday = formatUserBirthday(userData.userBirthday);
    const formattedAddress = displayUserAddress(userData.userAddress)

  return (
    <div className="user-card">
      <h2>{userData.userName}</h2>
      <p>Email: {userData.userEmail}</p>
      <p>Birthday: {formattedBirthday}</p>
      <p>Address: {formattedAddress}</p>
    </div>
  );
};

export default UserInfoCard;
```

#### 良かったこと

##### 関数の実装など、細かい処理ではなく、大枠を追うようにした

これは先輩からのアドバイスでもいただいたのですが、
getSomeInformation という関数を見たときに、どのように情報を取得しているのかを意識するのではなく、これは何らかの情報を取得しているのだな、という部分までの理解に留めることが大切だと感じました。
その上で、コードを追っていくくせをつけました。

```tsx
const formattedBirthday = formatUserBirthday(userData.userBirthday);
```

先ほどの例でいうと、formatUserBirthday の内部処理は全体像をつかむ上では大切ではなく、返ってきた formattedBirthday がフォーマット化された誕生日情報であるということを理解することが大切であるということです。
もちろん、内部実装は後で必要になれば見るべきだと思いますが、関数は無数にあり、1 つ 1 つを理解しようとするとまったく時間が足りないはずです。
そのため、コードの大枠を理解する上では must で追うべきではないと感じました。

---

##### そもそも自分は何のためにやっている処理を追おうとしているのか？をはっきりさせるようにした

たとえば、Next.js でバックエンドからデータを取得して、取得した情報をコンポーネントに渡して表示するという処理を読むときを考えます。
データの整形や処理を追い過ぎるのではなく、あくまでもデータを取得、表示だけに絞って追うようにすると、流れが掴めるようになった気がします。

とにかく細かい処理ではなく、やりたいことは何かを明らかにするというのが自分にとっては読めるようになったきっかけかもしれません。**あくまでもコードは手段に過ぎません。やりたいことがすべての土台であるべきだと思います。**

また、生成 AI を使い、**Mermaid** で思考フローを整理するのもおすすめです。
自分は視覚優位（目から入ってくる情報が覚えやすい）のため、以下のように Mermaid で思考を整理したりします。
フローチャートなども理解を助けるのに役立ちました。

<details>

<summary>
Next.jsでバックエンドからデータを取得して、取得した情報をコンポーネントに渡して表示するという処理の場合のNext.jsの流れを生成AIにMermaidで記述してもらったもの(PagesRouterの話です)

Mermaid live editor https://mermaid.live/

</summary>

```mermaid
sequenceDiagram
  participant ブラウザ
  participant Next.jsサーバー
  participant APIルート

  ブラウザ->>Next.jsサーバー: ページのリクエスト
  activate Next.jsサーバー
  Next.jsサーバー->>Next.jsサーバー: getServerSideProps実行
  activate Next.jsサーバー
  Next.jsサーバー->>APIルート: APIリクエスト
  activate APIルート
  APIルート->>データベース: データ取得
  deactivate APIルート
  APIルート-->>Next.jsサーバー: データを返す
  deactivate Next.jsサーバー
  Next.jsサーバー->>Next.jsサーバー: ページコンポーネントをレンダリング
  activate Next.jsサーバー
  deactivate Next.jsサーバー
  Next.jsサーバー-->>ブラウザ: HTMLを返す
  deactivate Next.jsサーバー
```

</details>

### コードが書けなかった

過去形のように書いてますが、現在進行形で取り組んでいる課題になります。まだまだ 0 から 1 まで完璧に作ることはできていないです。

#### 悪かったこと

##### 困ったらとりあえずわかりやすい技術記事ばかり読んでいて、とにかく読む量を増やしていた

要はインプットを重視し、自分がわからないことがあれば、わかりやすい記事に頼ってしまっていました。
ドキュメントは英語が多いので避けがちでした。

#### 良かったこと

##### 基礎的な学習を同時並行で行い続けた

結局は基礎力が大切であると痛感しました。Next.js や React 固有の知識を身につけたとしても、詰まったときはだいたい基礎の部分ができていないことが多かったです。
流れは以下です（Mermaid 擦りすぎてすみません）

```mermaid
flowchart TD
  A[Next.jsで困る] --> B[Reactで困る]
  B --> C[JavaScriptがわかっていない]
```

フレームワークやライブラリ固有の知識もありますが、基本は元をたどれば HTML, CSS, JavaScript の組み合わせだと思います。
そのあたりの知識が抜けたまま、フレームワークだけ極めてしまっても、新しくフレームワークが出たときに応用が利かなくなってしまいます。
そのため、[MDN](https://developer.mozilla.org/ja/docs/Web) や [JavaScript Primer](https://jsprimer.net/) は必要に応じて参照し、[LeetCode](https://leetcode.com/) などにも日々チャレンジしています!

---

##### 公式ドキュメントを読むようにした

これもありがちなことかもしれませんが、悪かったことでも書いた通り、ドキュメントは最初のうちは避けていました。
ですが、プロジェクトの内容を理解しようとして先輩とコードリーディングしているときに、先輩も私もわからないことがありました。
そのとき、一緒に公式ドキュメントをチェックしてすぐに解決できたことが、自分にとっての読むきっかけになりました。
読んでみると意外とわかりやすいし、記事では省略されていたプロパティや機能が多く書いてあるため、従来の記事に書いているよりも良い実装ができたのが自分にとっては感動でした。
思わぬ発見もあるので、とりあえず公式ドキュメントを一度最初にアクセスするようにしています。
英語というハードルはありますが、今は DeepL や翻訳、生成 AI に頼るなど、方法はたくさんあります。また、技術的な英語に慣れておくことで、ドキュメントを読むスピードも上げられると思いました!
(個人的には、YouTube で React や Next.js 周りの解説をしている人の動画を見るのも役立ちました!)

---

##### 手を動かしてコードを書くようにした

ちょっとした挙動の確認や、ドキュメントを読んだあとは、実際に使って動かせるような環境を用意しました。
[CodeSandbox](https://codesandbox.io/) や [TypeScript Playground](https://www.typescriptlang.org/play/)なども非常に有用です。
しかし、私は都度都度開くのが大変だったので、Next.js で動作確認用のリポジトリを作成し、React と TypeScript を使って常にローカルで確認できる環境を作りました。
実際に書くだけで、自分の中でのインプット具合が変わったと思います。手を汚すのは１番の学習だと思います!

---

### 質問ができなかった

リモートワークという環境もあり、質問はとくにハードルが高いと感じていました。

#### 悪かったこと

##### わからないと思ったことを全体の場で聞くのが恥ずかしかったので、メンターや先輩の方に個別のチャットなどで質問していた
ミーティング等で生じた疑問を、流れを止めてしまうかもしれないし、聞きづらいと思ってしまって後で聞くことが多かったです。結果、ミーティングの時点で聞いていれば、手戻りにならないようなこともありました。

##### わからないことを聞くだけで、確認の質問をあまり行わなかった。こんなこと聞いていいのかな？と思ってしまっていた。
疑問ばかり聞くことが多く、自分はこのように理解していますが合っていますか、という確認が取れていなかったです。あとから認識がずれていることに気づくこともありました。
また、こんな小さいことを聞いてもいいのかという心理的ハードルがあり、なかなか質問に至らないこともありました。

#### 良かったこと

##### わからない問題の切り分けを行うことにした

これは、わからないことが、プロジェクトに関することなのか、技術的なことなのかを切り分けることです。新人の私にとって、とくにプロジェクトに関することは、調べてもすぐには解決しない場合が多く、多くの時間を費やしてしまう傾向がありました。そのため、なるべく早くロスタイムを減らすために、どちらの質問なのかを意識して切り分けるようにしました。技術的な問題も、10-15 分調べてわからなかった場合は質問するようにしています。このように、自分なりの基準を設けておくことは大切だと思います。

> こちらも生成 AI に作成してもらった Mermaid

```mermaid
graph TB
    A[課題発生] --> B{技術的な課題?};
    B -- Yes --> C{調べる};
    B -- No --> D{プロジェクトの課題?};
    D -- Yes --> E{調べても解決しない?};
    E -- Yes --> F[わかる人に即訊く];
    E -- No --> G[解決];

    C -- 解決 --> G;
    C -- 未解決 --> H[時間制限内に解決?];
    H -- Yes --> G;
    H -- No --> I[技術強い人/訊きやすい人に訊く];
    I --> G;
    F --> G;
    G --> J[終了];
```

また、これと並行して行っていたこととして、都度詰まった時点で Slack の times チャンネル に投稿してみました。
さまざまな方が見てくれており、解決策を知っている人がいればすぐに答えていただけました。また、解決策を知らない人でも親切に調べて意見をくれるなど、広く意見が欲しいときに積極的に活用しています。

---

##### WOL を実施したこと

WOL とは、Working Out Loud のことで Slack などのチャットツールに今考えていること、悩んでいること、これからやろうとしていることをどんどん書き込みながら仕事をするスタイルです。いわゆる大声スタイルというものです。
今はあまりできていないですが、最初のころは自分が思ったことを書いてみて、それに反応してくれる方のおかげで疑問が解消されることが結構ありました。
個人にしか見えない形で質問してしまうと、答える方は限定されてしまいます。ですが、個人に宛てたメンションでも、オープンな場で質問するとそれ以外の方が答えてくれるときがあり、想像以上に見てくれているのだと感じました。また、自分以外にも知らない人がいることもあり、プロジェクトとして認識を合わせる機会になることもあると感じました。

---

##### 生成 AI を頼ったこと

正直、先輩に聞きたいことは山ほどありましたが、こんなの聞いていいんだろうかと思うことは多々ありました。
そんなとき、3 パターンの生成 AI の頼り方をしました。

1. 非常にしょうもないことを聞く
   聞きづらいけど自分がわからないことはガンガン聞いて理解を深めました。
   怒らないし、どんなことでも答えてくれて、人に聞くハードルもないので、今の時代を生きるエンジニアは積極的に活用すべきだと思います。（決して先輩に聞いたら怒るわけではないですw）
2. 抽象的な質問を具体化する
   もちろん、検索して答えが出るような質問であれば、検索して解決していました。
   ですが、なんて検索していいかわからない時も多々ありました。そういった悩みすべてを書いて、生成 AI に投げることで、抽象を具体の質問まで昇華させました。
3. 例え話をうまく使う
   難しい概念が出てきた場合は、積極的に別のものに例えて理解を促進させました。例えば、React の useEffect を理解するために useEffect を車で例えてと投げた場合、以下のような回答がされます。意外とわかりやすいのではないでしょうか。（たまに正確性を失う時があるので注意が必要です）

<details>
<summary>実際に聞いてみた</summary>

```md
useEffect は、コンポーネントが「走る」ためのエンジンのようなものです。
コンポーネント（車）が描画されるときに、エンジンが始動し、必要な処理を実行します。

## 走行中のチェック

車が走行している間、エンジンは常にチェックを行います。例えば、燃料の残量やエンジンの温度などを監視します。
これは useEffect が依存配列（第二引数）を使って、特定の状態やプロパティが変わったときにのみ処理を実行するのと似ています。

## メンテナンス

車には定期的なメンテナンスが必要です。例えば、オイル交換やタイヤの点検を行うために、車を整備工場に持っていくことがあります。
useEffect では、クリーンアップ関数を使って、コンポーネントがアンマウントされるときや依存が変わるときに不要なリソースを解放することができます。
これは、車のメンテナンスを行うことで、常に良好な状態を保つことに似ています。

## 目的地に到達するためのナビゲーション:

車が目的地に到達するためには、ナビゲーションが必要です。
目的地が変わると、ナビゲーションの設定を変更する必要があります。
useEffect も同様に、依存する値が変わると、それに応じて実行する処理を変えることができます。

## まとめ

useEffect は車のエンジンのように、コンポーネントが必要な処理を実行するための仕組みです。
依存配列を使って、必要なときにだけ処理を行うことができ、クリーンアップ関数を使ってリソースを管理します。
目的地の変更に応じて、ナビゲーションが調整されるように、useEffect も依存関係の変化に応じて動作します。
このように例えることで、useEffect の役割を理解しやすくなると思います。
```

</details>

:::note warn
会社によっては利用ルールがある場合があるので、事前に確認してから使うようにしてください!
:::

### その他

他にも技術以外にたくさんやってよかったことがあります。
それは、人との交流を積極的に行うことです。
今回あげた良かったことは、自分一人では成し遂げられなかったことがほとんどです。
社内 LT や開発合宿などにも参加し、さまざまな方からお話を聞けて非常に勉強になりました。
スムーズにサポートを受けられたのも、普段の交流あってのことだと思うので、これからも参加できるコミュニティにはガンガン参加しようと思います！

## まとめ

以上が 2024 年新卒入社してからの振り返りになります。
さもできるようになった感じで書いていますが、技術的にはまったくの未熟エンジニアで、毎日先輩たちすごいなと思いながら生きています。
ただ、少しずつ自分ができるようになっていく実感があります。
フロントエンドの領域をやり始めて、どんどん楽しいことが増えてきており、このままどんどん知識の幅を広げていきたいです。
そして、自分自身のエンジニアとしての価値を高めていけると嬉しいなと思います。

この記事を書いたきっかけは以下の記事を読んだのがきっかけです。
今年一番感銘を受けた良い記事なので、翻訳等上手く使いながら読んでいただけると良いと思います。
[Advice to the young](https://muratbuffalo.blogspot.com/2024/07/advice-to-young.html?ref=dailydev)

2025 年はよりできることを増やせるよう、今までやってきたことに＋ α で意識することを増やしていき、自分ひとりでできる仕事を増やしていきたいと思います。
この記事がどこかの誰かのためになると嬉しいです。
お読みいただきありがとうございました！！