🦷

ReaSemi(議事録Vol.2)

2024/08/06に公開4

2024.08.02 22:00~
りあゼミ!第2回議事録はMariがお送りさせていただきます!

【本日の内容】

①『Re:りあゼミ!』:初参加OK!前回学んだ内容でウォームアップ✨
②『Viteで3分クッキング』:簡単にReact環境構築!
③『30分チーム開発』:カウンターアプリを作ってレビューしあおう!

①『Re:りあゼミ!』:初参加OK!前回学んだ内容でウォームアップ✨

前回の復習内容についてはこちらの記事から確認してみてくださいね!
https://zenn.dev/reasemi/articles/eba9e0ce346817

本日の復習ポイント

JSXの構文で重要なところです!

App.jsx
const App = () => {
  console.log("Hello,world!");
  // returnより前はJSの関数が書ける世界
  return <p>Hello,world!</p>;
};

JSXは、HTMLのファイルとJavaScriptのファイルとを行き来しなくても一つの画面で
"処理"と"返ってくる結果"までがわかりやすいという特徴があります。

さて、ここで問題です!

  • Q.const animal = "Cat"と定義して、Catと表示させるためにreturnのあとには何が入るでしょうか?
    ここまで、returnの前後で書けるものの世界が違うというお話をしてきましたが、
    実は、returnのあとにJavaScriptの変数を出力することができます。

❌NG❌

App.jsx
const App = () => {
  const animal = "Cat"
  return <p>animal</p>;
};

これではそのまま
 animal
が表示されるだけですね。

正解は…
App.jsx
const App = () => {
  const animal = "Cat"
  return <p>{animal}</p>;
};

{}で囲うとJavaScripの世界がまた戻ってきてくれます。
(パラレルワールド!?)


React便利だけど毎回環境構築するのは結構手間かかるよね…
もっとお手軽にパパッと環境構築できないのー!
ドラ◯もーーーん!

テッテレー!
ここで前回見送られたViteの登場です🧙‍♀️🪄

②『Viteで3分クッキング』:簡単にReact環境構築!

Reactの環境構築、プロジェクトディレクトリごとに毎回設定しなきゃなんですよね。
一発で!とまではいかないけど、
環境構築の"ビルド"の部分を時短できるものが、Vite(ヴィート)です。

Viteとはなんぞ?
早速解説記事をUPしてくれたので、詳しくはこちらの記事をご確認ください。
https://zenn.dev/reasemi/articles/6869cebde469aa

やまぴー先生が実際に説明しながらViteでビルドしたところ、
なんと1分!!!!!

代表的なビルドシステムの違い

  1. Create React App:少し前まで使われてたけど、2022年4月から更新されていない(例:オートマ車)。
  2. webpack:チーム開発向け。オールインワンになっている設定をさらにカスタマイズできる(例:マニュアル車)。
  3. Vite:個人でサクッと開発したいとき向け。ビルドの高速さが売り。webpackのように設定のカスタマイズはしにくい。

ディレクトリ構成の違い

webpackとViteでビルドしたディレクトリ構成の違いをそれぞれ見てみましょう!
(ここのパートは少し長くなってしまったので、軽く流し見してください。笑)

/react-wp/
├── node_modules/
├── src/
│   ├── components/
│   │   └── etc...
│   ├── css/
│   │   ├── reset.css
│   │   └── style.css
│   ├── App.jsx
│   ├── index.html
│   └── main.jsx
├── package-lock.json
├── package.json
└── webpack.config.js   …❶
/vite-project/
├── node_modules/
├── public/
│   ├── vite.svg        # 画像
├── src/
│   ├── assets/
│   │   └── vite.svg    # 画像
│   ├── App.css
│   ├── App.jsx
│   ├── index.css
│   └── main.jsx
├── .eslintrc.cjs       …❷
├── .gitignore          …❸
├── index.html
├── package-lock.json
├── package.json
├── README.md
└── vite.config.js      …❶

ちょっとした違いはあるもののそこまで大きな違いはないです。
❶ webpack.config.jsに色々書かれているのに対して、
 vite.config.jsはわずか7行。シンプルイズザベスト。
ここが超シンプルなためにあまりカスタマイズできないよーということですね。

❷.eslintrc.cjs (ESLint)について
vite-projectのREADME.mdにはこんなことが書かれてました(一部抜粋です)。

『このテンプレートは、ViteでReactを使用するための最小限のセットアップを提供し、
 ESLintルールを含んでいます。』

.eslintrc.cjs ←これがESlintです。ここでルールを設定します。
Viteだから入っているという訳ではなくデフォルトで入ってるだけで、他でも使えます。

VSCodeの拡張機能でPritterがありますが、こちらはフォーマットを揃えてくれます。

  • 半角スペース何マス空けるか揃える
  • ""か''か統一
    など

一方、ESLintは、コードを特定のルールに則って変換し、コードの品質を保ってくれます。

  • クラス名をアルファベット順に並べ替え
  • 最初のImport文をある特定のルールで並び替え
    など

PritterとESLintの使い分けはこちらが参考になるかと思います。
https://zenn.dev/mami_inuzuka/articles/3deb24e2726ce9

❸.gitignoreについて
ignore…無視する、という意味です。
Gitであげるときに、一緒にあげたくないものを記述しておくことができます。

  • node_modules/ (重たいから)
  • パスワードとか個人情報のデータベース
    など

CSSは、style.cssか個別のCSSか、という違いもありました。

(ここまで長くなってしまいましたが…)
以上、Vite 3分"1分"クッキングでした!笑


③『30分チーム開発』:カウンターアプリを作ってレビューしあおう!

2チームに分かれてカウンターアプリを開発しました。

VSCodeの拡張機能「Live Share」を使って、チームで同時に共同編集が行える便利な機能です。(読み取り専用も設定できます)
https://zenn.dev/sugarperson/scraps/53de7f4a63fbf4
招待される側の解説はこちら
サーバーの共有方法はこちら

無事リアルタイムで編集内容が反映されていき共同コーディングできるようになったー!
と喜んでいましたが、
ゲストユーザー側でローカルサーバーの画面が反映されない問題が発生…
チーム1でも同じ現象だったようです。

なぜゲスト側でローカルサーバーが立ち上がらないのか?
Viteとの相性が悪い?
次回はこの検証を行うこととなりました。


いざ!チーム開発!

各チームのコードはこちら

チーム2 ごはんおかわりカウンター🍚

team2
import { useState } from "react";
import "./App.css";

function App() {
  // 初期値を0にする
  const [number, setNumber] = useState(0);

  return (
    <>
      <div style={{ border: "1px solid black", padding: "10px" }}>
     {/* {}でJSの世界が戻ってきます */}
        <p style={{ fontSize: "50px", fontWeight: "bold" }}>ごはん{number}</p>
        {/* ボタンを押すとsetNumberが更新されていく */}
        <button onClick={() => setNumber(number + 1)}>おかわり</button>
        <button onClick={() => setNumber(number - 1)}>お残し</button>
        {/* 0にリセット */}
        <button onClick={() => setNumber(0)}>おえぇ</button>
      </div>
      {/* おまけ 10杯以上になったら"おなかいっぱい"を表示 */}
      {number >= 10 ? (
        <p style={{ fontSize: "50px", fontWeight: "bold" }}>おなかいっぱい</p>
      ) : null}
    </>
  );
}

export default App;

チーム1 Kさんの歯は何本でしょか?🦷

team1
import { useState, useEffect } from "react";
import "./App.css";

const styles = [
  { fontSize: "3em" },
  { fontSize: "0.5em" },
  { transform: "rotate(180deg)" },
  { color: "red" },
  { color: "blue" },
  { fontWeight: "bold" },
];

const rainbowColors = [
  { color: "red" },
  { color: "orange" },
  { color: "yellow" },
  { color: "green" },
  { color: "blue" },
  { color: "indigo" },
  { color: "violet" },
];

function App() {
  const [count, setCount] = useState(0);
  const [style, setStyle] = useState({});

 // 3の倍数でstyleがランダムに当てられる
  useEffect(() => {
    if (count % 3 === 0 && count !== 0) {
      const randomStyle = styles[Math.floor(Math.random() * styles.length)];
      setStyle(randomStyle);
    } else {
      setStyle({});
    }
  }, [count]);

  const onClickIncrement = () => {
    setCount((count) => count + 1);
  };

  const onClickDecrement = () => {
    setCount((count) => count - 1);
  };

  const onClickReset = () => {
    setCount(0);
  };

  return (
    <>
      <h1 className="rainbow-text">
        <span style={rainbowColors[0]}>T</span>
        <span style={rainbowColors[1]}>e</span>
        <span style={rainbowColors[2]}>a</span>
        <span style={rainbowColors[3]}>m</span>
        <span>-</span>
        <span style={rainbowColors[4]}>o</span>
        <span style={rainbowColors[5]}>t</span>
        <span style={rainbowColors[6]}>s</span>
        <span style={rainbowColors[0]}>u</span>
        <span style={rainbowColors[1]}>m</span>
        <span style={rainbowColors[2]}>a</span>
        <span style={rainbowColors[3]}>r</span>
        <span style={rainbowColors[4]}>u</span>
      </h1>
      <div className="count">
        <span style={style}>Kさんの将来の歯の数:{count}</span>
      </div>
      <button onClick={onClickIncrement}>はやす</button>
      <button onClick={onClickDecrement}>抜く</button>
      <button onClick={onClickReset}>reset</button>
    </>
  );
}

export default App;

おもしろポイントはたくさんありますが、ご自身で読み解いてみてください。
両チームの個性溢れる作品に腹筋が鍛えられました。笑

両チームのプラスボタンの違いに注目です。

team2
<button onClick={() => setNumber(number + 1)}>おかわり</button>
team1
const onClickIncrement = () => {
  setCount((count) => count + 1);
};
<button onClick={onClickIncrement}>はやす</button>

チーム2は、インライン関数、
チーム1は、コールバック関数を使っています。

  • インライン関数
    この方法は簡潔で、直接的に値を更新するのに適しています。しかし、現在のnumberの状態に依存しているため、更新が非同期である場合に予期しない動作が発生することがあります。
    (ごはんを1杯食べ終わる前におかわりしても、前のごはんを完食していないので2杯になりません。お残しダメダメ。)

  • コールバック関数
    この方法は、setCountがコールバック関数として前の状態(count)を引数に取り、それに基づいて新しい状態を計算するものです。この方法は、更新が非同期で行われる場合でも安全で、複数の状態更新が同時に行われる場合に有効です。
    (Kさんの歯を1本をはやす処理が終わる前に更にもう1本はやす処理を始めても、同時に実行されるので無事2本はえてきます!!よかった!!)


最後に、useStateについてまとめです。

state:データの状態を記憶させておく「変数」
setState:データの状態を更新する「関数」
useStateにはstateの初期値が入ります。
(例)
朝食に例えると、初期値ごはん、ボタンを押すとパンに変更。

import { useState } from "react";

const Breakfast = () => {
  const [menu, setMenu] = useState("ごはん");

  return (
    <div>
      <p>朝ごはんは {menu} です</p>
      <button onClick={() => setMenu("パン")}>朝ごはんをパンにする</button>
    </div>
  );
}

export default Breakfast;

私は自分なりに言葉を当てはめてみたり、図にしてみたりするとスッと理解できるのでぜひ皆さんも自分のアウトプットをシェアしていきましょーー!!


感想

わいわいしながら遊び感覚で、でも勉強になる、そんなチーム開発でした。
…と言いつつも、自分のチームはどんなアプリにしていこうか会話するものの、メンバー1人にコーディングほぼお任せ状態になってしまった…申し訳ありません…。
勉強不足を痛感しました😭{スラスラ手を動かせるようになりたい!!

議事録担当しましたが、遅くなりましてすみません。
めっっちゃ楽しくてテンション高めすぎたので修正してました。笑
どんな伝え方したらわかってもらえるかな、と噛み砕いていく最中で自分の思考整理にもなりました。
(各チームのコード等に間違いがありましたらご指摘お願いします!)

引き続きアウトプットすることと、小さいアプリをがんがん作って練習していきたいと思います!
React道場やりましょう!笑
練習になりそうなお題、じゃんじゃん!お待ちしております!
(9期生:Mari)

りあゼミ!

Discussion

やまぴー / YAMAGUCHI Tomohisaやまぴー / YAMAGUCHI Tomohisa

なんて読みやすいんだ...!
Mariさん最高な記事をありがとうございます!!

MariMari

ありがとうございます😭✨
チーム開発ではなにもできなかったのでもっと色々作って体が覚えてくれるくらいになります🔥

NanaNana

Mariさんって、元々記事書いてらしたんですか?!
分かりやすすぎて感動しました><
内容再確認しながら復習します!ありがとうございます!

MariMari

記事書いたのは初めてですー😂
自己満で楽しんでるだけじゃないか不安です笑
そんな風に言ってもらえて励みになりますありがとうございます🙇🏻‍♀️✨