WASD TECH BLOG

WASD Inc.のTech Blogです。

Hasuraを使ってReactでTodoアプリをサクッと作ろう 完結編

WASD Inc. で開発をしている Yutorin です。

弊社のデジちゃいむでも採用しているHasuraとReactを使ってサクッとTODOアプリを引き続き作っていきましょう。

前回はこちらです。

tech.wasd-inc.com

今回は実際にHasuraとReactアプリとのつなぎ込みを行い、超簡単なTodoアプリを作っていきます。




目次

  • はじめに
  • Apolloを導入する
  • Queryを動かしてTodo一覧をとる
  • Mutationを動かして追加する
  • これから
  • あとがき


続きを読む

Hasuraを使ってReactでTodoアプリをサクッと作ろう React立ち上げ編

WASD Inc. で開発をしている Yutorin です。

弊社のデジちゃいむでも採用しているHasuraとReactを使ってサクッとTODOアプリを引き続き作っていきましょう。

前回はこちらです。

tech.wasd-inc.com

今回はReactのパッケージを導入し、GraphQL Code Generatorを動作させるところまで行います。




目次

  • Reactを用意する
  • GraphQL Code Generator を導入する
    • Graphql Code Generatorとは?
    • 導入してみる
    • 動かしてみる
  • あとがき


続きを読む

react-hook-formのSubmitHandlerを利用したonSubmit処理の返り値に型をつける

ワスド株式会社 開発チームのmako_jiiです。 今回は「react-hook-formのSubmitHandlerを利用したonSubmit処理の返り値に型をつける」と題しまして、記事を書かせていただこうかと思います。

なぜこの記事を書こうと思ったかというと、react-hook-formを使用した実装中で詰まったところがあったからです。

下記画像のように、useFormを使用する場合form部分のみ別コンポーネントに切り離して実装することが弊社では多いです。 form の状態管理にはreact-hook-formを使用しており、バリデーションにはclass-validatorを使用しています。

// Settings.tsx
import React from "react";
import { SettingsForm, OnSubmitSettingsFormValues } from "components/SettingsForm";

const Settings: React.FC = () => {
  const onSubmit: OnSubmitSettingsFormValues = async (data) => {
    await updateSettings(data); // DB更新処理など
  };

  return (
    <SettingsForm onSubmit={onSubmit} />
  );
};
// SettingsForm.tsx
import React from "react";
import { useForm, SubmitHandler } from "react-hook-form";

class SettingsFormValues {
  @IsNotEmpty({ message: "住所を入力してください" })
  address: string;

  @IsNotEmpty({ message: "名前を入力してください" })
  name: string;
}

export type OnSubmitSettingsFormValues = SubmitHandler<SettingsFormValues>;

export type SettingsFormProps = {
  onSubmit: OnSubmitSettingsFormValues;
};

const SettingsForm: React.FC<SettingsFormProps> = ({ onSubmit }) => {
  const { register, control, handleSubmit } = useForm<SettingsFormValues>();

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {/* テキストボックスとか */}
    </form>
  );
};

useFormform周りにまつわる部分のみ別コンポーネントに切り離しますが、
formで入力した内容に基づいたDBの更新処理などはメインのコンポーネントに置いておいて、引数でその関数を渡しています。
更新処理の関数の型は、formコンポーネントで作成した型にしております。

formの値が変更された時のみ保存ボタンを活性化させるために、DBに保存してある値でformの初期値を設定することに加え、
保存後に保存ボタンを非活性化させるために、保存後の値でformの初期値をresetさせる実装をしました。

// Settings.tsx
// onSubmit処理のみ記載
const onSubmit: OnSubmitSettingsFormValues = async (data) => {
  const { address, name } = await updateSettings(data); // DB更新処理など
  return { address, name }; // 返り値でオブジェクトを返す
};
// SettingsForm.tsx
// importや型定義は省略

const SettingsForm: React.FC<SettingsFormProps> = ({ onSubmit }) => {
  const { register, control, reset, handleSubmit } = useForm<SettingsFormValues>();

  // SettingsForm内でラップする
  const _onSubmit: OnSubmitSettingsFormValues = async (data) => {
    const result = await onSubmit(data);
    reset(result);  // anyを渡してしまい危険なコードになる
  };

  return (
    <form onSubmit={handleSubmit(_onSubmit)}>
      {/* テキストボックスとか */}
    </form>
  );  
};

がしかし、 コード内にも書いてあるとおりanyresetに渡ってしまい危険なコードになってしまいます。 なんでかというとreact-hook-formSubmitHandlerがそういう型定義をしているからです。

なんとか型推論させて安全にしてあげたい、
いろいろな解決方法があるかと思いますが、今回はプロパティの定義にclassを使用したためinstanceofを使って型を判定させることにしました。

developer.mozilla.org

// Settings.tsx
// onSubmit処理のみ記載
const onSubmit: OnSubmitSettingsFormValues = async (data) => {
  const { address, name } = await updateSettings(data); // DB更新処理など
  return { address, name }; // 返り値でオブジェクトを返す
};
// SettingsForm.tsx
// _onSubmit処理のみ記載

// SettingsForm内でラップする
const _onSubmit: OnSubmitSettingsFormValues = async (data) => {
  const result = await onSubmit(data);  // resultはオブジェクトであってインスタンスではないので、このif文はfalseになってしまう
  if(result instanceof SettingsFormValues) {
    reset(result);
  }
};

SettingFormValuesと同じ形のオブジェクトを渡して、型判定をinstanceofで行うようにコーディングしてみましたが、
コメントにも記載したようにif文の判定がfalseになってしまい意図した動作をしません。
調べた結果、値を返す時にオブジェクトを返しているのでSettingFormValuesクラスのインスタンスではないと判定されることが原因と分かりました。

そこで、プロパティを定義したclassconstructorを追加し初期値を載っけられるようにして、

// SettingsForm.tsx
// 処理なのは変更なしのため省略
export class SettingsFormValues {
  @IsNotEmpty({ message: "住所を入力してください" })
  address: string;

  @IsNotEmpty({ message: "名前を入力してください" })
  name: string;
  
  constructor(address:string, message:string) {
    this.address = addess;
    this.message = message;
  }
}

return newで返したい値をSettingFormValuesインスタンスで返すようにしました。

// Settings.tsx
// onSubmit処理のみ記載
const onSubmit = () => {
  const result = UpdateDBProcess(); // 更新処理
  return new SettingsFormValues(result.address, result.name);
};

うまくいきました!

返り値を扱っている時はanyですが、ifブロック内でresultは型推論されている状態で使用することができます。

以下最終形態です。

// Settings.tsx
import React from "react";
import {
  SettingsForm,
  OnSubmitSettingsFormValues,
  SettingsFormValues,
 } from "components/SettingsForm";

const Settings: React.FC = () => {
  const onSubmit: OnSubmitSettingsFormValues = async (data) => {
    const { address, name } = await updateSettings(data);  // DB更新処理など
    return new SettingsFormValues(address, name); // 返り値でインスタンスを返す
  };

  return (
    <SettingsForm onSubmit={onSubmit} />
  );
};
// SettingsForm.tsx
import React from "react";
import { useForm, SubmitHandler } from "react-hook-form";

// Settings.tsxで使うのでexport
export class SettingsFormValues {
  @IsNotEmpty({ message: "住所を入力してください" })
  address: string;

  @IsNotEmpty({ message: "名前を入力してください" })
  name: string;

  // コンストラクタを定義
  constructor(address: string, name: string) {
    this.address = address;
    this.name = name;
  }
}

export type OnSubmitSettingsFormValues = SubmitHandler<SettingsFormValues>;

export type SettingsFormProps = {
  onSubmit: OnSubmitSettingsFormValues;
};

const SettingsForm: React.FC<SettingsFormProps> = ({ onSubmit }) => {
  const { register, control, handleSubmit } = useForm<SettingsFormValues>();

  // SettingsForm内でラップする
  const _onSubmit: OnSubmitSettingsFormValues = async (data) => {
    const result = await onSubmit(data);
    if(result instanceof SettingsFormValues) {
      reset(result);
    }
  };

  return (
    <form onSubmit={handleSubmit(_onSubmit)}>
      {/* テキストボックスとか */}
    </form>
  );
};

あるいは別解として、class-transformerというライブラリ中のplainToInstance関数を利用して、オブジェクトをクラスに変換することでも正しく動作します。
こちらの方がコード量も少なく、よりよい実装かもしれません。
この場合、classconstructorは不要となります。

github.com

// Settings.tsx
// onSubmit処理のみ記載
const onSubmit: OnSubmitSettingsFormValues = async (data) => {
  const { address, name } = await updateSettings(data);  // DB更新処理など
  return { address, name };
};
// SettingForms.tsx
// _onSubmit処理のみ記載

// SettingsForm内でラップする
const _onSubmit: OnSubmitSettingsFormValues = async (data) => {
  const result = await onSubmit(data);
  const values = plainToInstance(SettingsFormValues, result);
  if(values instanceof SettingsFormValues) {
    reset(result);
  }
};

かなり具体的なユースケースで発生した問題ですが、紐解いてみると解決にはTypeScriptのしっかりとした実力が求められ、改めて勉強になりました。
今後も、WASD TECH BLOGでは開発チームの取り組みや、 React, TypeScript, GraphQL, Hasura, AWS といった技術スタックについての記事を定期的に発信していきます。よろしければ過去記事や、 もよろしくお願いいたします。

以上、mako_jiiでした。

MUIのButton Componentの中のアイコンに自作のSVGを使用する方法

WASD Inc. 開発チームのYubaです。

弊社ではUI ComponentライブラリのMUIを活用してComponentを作成しています。

mui.com

その中で、MUIのButtonコンポーネント中のアイコンに自作ののSVGを使用したところ、コンポーネントのスタイルが崩れてしまうという問題が発生しました。 本記事では、その問題の調査から解決に至るまでの過程を紹介します。

問題の背景

弊社のプロダクトのデジちゃいむではGoogleクチコミ連携という機能があり、店舗とGoogle Maps上の店舗のデータとひも付けて、店舗でデジちゃいむを使用したユーザーをGoogle Maps上の店舗のクチコミへ誘導するという機能があります。

この機能を実装するにあたり、今回はこのGoogleでクチコミのボタンを作成しました。

MUIのButton ComponentにはStartIconというPropsの機能があり

SVGのComponentなどをPropsで渡すことで文字列より先頭にアイコンを表示できます。

<Button variant="outlined" startIcon={<DeleteIcon />}>
  Delete
</Button>

mui.com

Googleでクチコミボタンでも同様にGoogle MapsのアイコンのSVGをComponentで独自で作成しstartIconに<GoogleMapIcon/> 渡すように実装を行いました。

 <Button
  variant="contained"
  startIcon={<GoogleMapIcon />}
  sx={{
    backgroundColor: "white",
  }}
 >
  <Typography variant="h5" sx={{ lineHeight: "2em", fontWeight: "bold" }}>
    Google でクチコミ
  </Typography>
 </Button>

この実装ではアイコンのSVGが小さくなってしまう、テキストとのmarginが少し空きすぎてしまうなどの問題が発生しました。

原因と解決策

ChromeのDevToolsで確認するとSVGのstartIconのnth-of-type(1)fontSize:20px が当たっていることがわかり、この影響によりアイコンが小さく表示されているので適切な大きさに上書きをする必要がありました。

.css-1d6wzja-MuiButton-startIcon>*:nth-of-type(1) {
  font-size: 20px;
}

MUIではComponentのclassセレクターを上書きする方法として、ComponentのClassesをimportしsx Propsから上書きをすることができます。この方法はClassesを提供している他のComponentでも使用できます。

mui.com

自前でclassをを定義してclassName経由で渡してスタイルを適用することも可能ですが、importしたClassesをsx Props経由で使う方がTypeScriptで安全に書きやすいです。

sx Propsで .${buttonClasses.startIcon}からstartIconのclassを直接指定して下記の用にmarginを加え、nth-of-type(1) のfontSizeを32pxに指定することでスタイリングの調整ができスタイリングの問題が解消することができました!

import { Button } from "@mui/material";
import { buttonClasses } from "@mui/material/Button";

<Button
  variant="contained"  
  startIcon={<GoogleMapIcon />}
  sx={{
    ...
    [`& .${buttonClasses.startIcon}`]: {
      mt: "-2px",
      mr: "4px",
      "&>*:nth-of-type(1)": {
        fontSize: 32,
      },
    },
  }}
>
  <Typography variant="h5" sx={{ lineHeight: "2em", fontWeight: "bold" }}>
    Google でクチコミ
  </Typography>
</Button>

Classesを使う際の注意点

MUIのComponentのClassesを使う上での注意点ですが、VScodeなどでサジェスト通りのimportを行うと下記のようにClassesを直接importしている場合があるのですが、このimportではbuttonClassesを使用できずエラーが出るので

import { buttonClasses } from "@mui/material/Button/buttonClasses";
import { buttonClasses } from "@mui/material/Button"

この様に書く必要があります。

MUIでは1st Levelと2nd Levelからのimportのみをサポートしていて、それより深い階層のimportはプライベートとみなされるのが理由のようです。

mui.com

まとめ

MUIを使用するとさまざまなコンポーネントを簡単に作成できますが、今回のように特殊なコンポーネントの作成をしたいとなった場合はカスタマイズの方法を調べてを実装を行う必要がありました。プロダクトを作っていくにあたっては特殊な表示の実装を行うことも多いのでMUIを使っていくに当たっての知識もどんどん取り入れていく必要があるなと思いました。

弊社では今後ともMUIを使ってさまざまな物を開発していくので、いろいろなTipsなどを発信していければと思っています!

WASD TECH BLOG では主に React、TypeScript、GraphQL に関する記事を定期的に発信します。

よろしければ他の記事や、もお願いします。

ワスドのスクラム開発で芋煮会をやっている話

ワスド株式会社 Development Division(開発チーム)の okkun です。

弊社では「デジちゃいむ」という店舗向け呼び出しシステムを開発しています。その中で、開発チームでは SCRUM BOOT CAMP THE BOOK を共通の参考図書とした上で、スクラムをチームにフィットするようカスタマイズし運用しています。

digichime.com

スクラムとは?

ラグビースクラムが由来してます

そもそもスクラムとはアジャイル開発という概念を達成するために考案されたフレームワークです。

大きな特徴として、

  • スプリントという予め決めた1週間〜1ヶ月の期間で区切って繰り返し開発すること
  • そのスプリントの最初に決めたスプリントゴールの達成に向けてチームが一丸となって取り組むこと

が挙げられます。

スクラム開発では、

  • 5つのイベント
  • 3つのロール(役割)
  • 3つの成果物

が定義されており、メンバーそれぞれが持つ役割を全うしチームで協力して成果物の完成を目指します。

後述で登場する一部のものについてここで簡単に説明します。

スクラムマスター

スクラムチーム(開発者、ステークホルダー:利害関係者)の業務をスムーズにするため、ファシリテートを行ったりチーム外からの干渉(割り込みで発生するタスクなど)からチームを守る役割を持つ人物。

プロダクトバックログ

プロダクトの改善に必要なものをまとめた一覧。Todoリストのようなもの。

スプリントレビュー

直近スプリントの成果物をチームで確認するための場。

スプリントプランニング

次のスプリントの方針を定め、どの課題の改善に着手するかを決める場。

スプリントレトロスペクティブ

直近スプリントについての振り返りの場。 スプリント中に発生した問題や解決方法などをチームに共有し、次回以降のスプリントに生かすことでプロダクトの品質向上に繋げられる。また、プロダクトバックログの中身について再度精査し、必要に応じて優先度などの再調整も行う。

その他のものについては下記SCRUM GUIDESにドキュメントがありますのでこちらをご覧ください。 サイト自体は英語ですが、日本語のドキュメントも掲載されています。

scrumguides.org

ワスドなりにカスタマイズしている点

スプリントについて

弊社では1スプリントを水曜〜翌週水曜の1週間としています。

私が入社した時点では既に水曜日がスプリントの区切りでしたが、聞いたところ、以前は金曜日をスプリントの区切りとしていたようです。 これは、金曜日に向けて開発を集中していくという点でリズムは作りやすかったのですが、

  • 週明けにやることを思い出すところから始まってしまう
  • 金曜日に有給をとりづらい

などの理由から水曜日に移したという経緯があったようです。

スプリントの周期と曜日は最も基本的ですが、開発体制に大きく影響を与えるファクターだと思います。

使っているツールについて

弊社はドキュメントツールとして全社的に Notion を使用しています。

開発に関わるプロダクトバックログも Notion 上で管理することで、インターンを含め社内関係者が誰でも見れる風通しのいい環境を作っています。

プロダクトバックログへの起票は誰でも行っていいことになっています。

www.notion.so

ちなみに、私の入社以前は JIRA でプロダクトバックログの管理を行っていました。 スクラム専用のツールだけあってストーリーポイントやバーンダウンチャートなどの機能が備わってあります。

Notionにもこれらの機能がほしいと感じることもありますが、Notionは頻繁にアップデートされていますので今後の機能追加に期待したいです。

www.atlassian.com

プロダクトバックログの考え方

プロダクトバックログ上に起票されるものは単なる「タスク」ではなく「ユーザーストーリー」として扱われ、ユーザーに提供される価値に焦点が当てられます。

具体的には、「どんなペルソナが」「どんな結果を得られるように」「そのために我々が何をするのか」という視点で起票されます。

そのため、具体的な実装方法や実装方針等はここでは起票せず、GitHub Issueとしてまとめて開発チーム内で議論を行います。

asana.com

その他のミーティングの進め方

ワスドでは専任のスクラムマスターは置いておらず、スプリントレビューは開発チームが主体となって運用、プロダクトバックログはビジネスチームと開発チームが協力して運用、という形をとっています。

デイリーミーティングは毎日10時に行っています。 この場で前日やったこと、今日やること、進行で困っていることなどを共有します。

振り返り(スプリントレトロスペクティブ)は月1回で行っていますが、これは毎週行っているとKPTを無理やり絞り出したりして形骸化する可能性があるためで、この間隔で丁度いいように感じています。

「このあと芋煮会よろしくお願いします。今日は長芋です。」

楽しそうに芋を煮る社員の様子

誰が言い出したのか、社内ではプロダクトバックログ「欲しいものリスト」「干し芋と呼ばれ、そこから派生しスプリントプランニングは芋煮会と呼ばれています。

月1のスプリントプランニングは長めの芋煮会ということで「長芋」「ポテロング」などと呼ばれており、スプリントレビュー後にスプリントプランニングを行う日の場合は、

「このあと芋煮会よろしくお願いします。今日は長芋です。」

という会話が発生しています。ここまでくると何が何だかわかりません。(そもそも干し芋って煮るのかな...?)

親しみやすい名称を使うことで社内全体を巻き込みやすくなっているというメリットがありますが、一方で正式名称が浸透していないことで正しい理解に辿り着き伝いというデメリットもあります。

「スプリントプランニング」という単語を知ってれば検索してそれに関する記事を見ることができますが、「芋煮会」と検索しても私の出身である山形の芋煮会フェスティバルの記事が出てきてしまいます。

記事冒頭で挙げたSCRUM BOOT CAMP THE BOOKを開発チームの参考図書としているのはこういった背景もあるためです。

おわりに

この開発スタイルは私が入社する以前から運用されていたため、この記事を書くにあたっても初期からいるメンバーに背景などを教わり初めて知ることもありました。

立ち上げ期のスタートアップの開発ではメンバーもスケジュールも限られていることが多く、その中でユーザーに少しでも早く価値を届けることを考えた時にテンプレ通りのスクラムでは成立しないこともあります。

組織やプロダクトが大きくなるにつれて課題も変わっていくと思うので、その時点でのよりよい方法を開発チーム内外で協力して模索しつつ、価値のあるサービスを提供し続けたいです。

そのためにもまずは SCRUM BOOT CAMP THE BOOK などで一般的な知識を得た上で現状を分析することが重要だと思いました。

「プロを目指す人のためのTypeScript入門」の輪読会をはじめました!

WASD Inc. 開発チームマネージャーの U76NER です。

この度、開発チームで輪読会を行うことになり、その第1回が開かれました。 本記事では、輪読会を行うことに至った経緯や、輪読会へのチームメンバーの感想をご紹介します。

輪読会とは

人々が集まって、同じ教科書などの本を読み、その内容について意見を交わすことを意味する語。事前に決められた担当者が、本の内容を訳したりまとめたりしてから、他の参加者が理解できるように発表する形式がとられることも多い。

輪読会(りんどくかい) - Weblio辞書

輪読会の形式は様々ありますが、弊社の開発チームでは、以下の通りのオーソドックスなスタイルで輪読会を行っています。

  • 章ごとに担当者を決めて、事前に内容をまとめたスライドを用意する。
  • 他の参加者も、あらかじめその回の内容について読み進めておく。
  • 日程を決めて定期的に行う。

なお、開発チームでは金曜日の午前中を文章をアウトプットする時間と位置付けており、これまでもこの時間で、ドキュメントや対外発信の記事を書いたり、社内でLT会を行ったりしてきました。 この輪読会も、その中での扱いとして行われるものです。

(LT会については別途記事がありますので、ぜひご覧ください。) tech.wasd-inc.com

開催の経緯

輪読会を行ったのは、タイトルにもあるこちらの本、いわゆるブルーベリー本が発売されて話題になったのがきっかけでした。

gihyo.jp

チーム内でも発売して話題に上がることがありましたが、弊社CTOの進木が先行して目を通したところ、非常に実践的で良い本だったのと感想がありました。

開発の話になりますが、弊社プロダクトのデジちゃいむは、開発言語としてフロントエンド、バックエンド双方でTypeScriptを採用しています。

digichime.com

チームメンバーはほとんどがソフトウェア開発経験がありますが、デジちゃいむのプロジェクトで初めてTypeScriptでの開発に携わったというメンバーが多い状況です。そのため、TypeScriptの言語仕様からくる特有の実装技術などについては、個々の実装やレビューを通してOJT的に身に着けており、TypeScriptを体系的に学ぶ必要性を感じていました。

この本を読むことでTypeScriptについての教育コストがかなり削減されるため、ぜひ全員で内容を共有したいということになり、輪読会を行うに至りました。 すなわち、輪読会を行うにあたって題材となる本を選んだのではなく、チームで共有したい本があるため輪読会という形式を選択した、ということになります。

(私も本を読み進めていますが、今までコーディングで無意識に行っていたことが言語化されていて、とても納得感があります。)

なお、本書中のコラムは特に実践的であり、実力のステップアップに最適なため、コラムについては担当者がまとめることをあえてせず、メンバー全員で内容を確認することにしています。

輪読会の感想

輪読会の第1回は5/20(金)に行われました。参加したメンバーからは以下のような感想がありました。

  • TypeScriptを体系的に学ぶことができてよかった。特に、実務ではなかなか触れない歴史的経緯や正確な用語などについて知ることができた。
  • デジちゃいむの実装と結びつけることで、より理解が深まった。
  • ドキュメントとして残し切れていない部分を浸透させることができた。
  • ディスカッションを通じて、本の内容だけにとどまらない有機的な知識を得ることができた。
    • 例えば、コードフォーマッタや浮動小数点数の演算精度などに話が及びました。

おわりに

本記事では、弊社開発チームで行っている輪読会についてご紹介しました。 輪読会を行うことで、TypeScriptの技術力向上という具体的なメリットがあることが明確なので、メンバーも非常に高いモチベーションで取り組んでいます。

今後も、WASD TECH BLOGでは開発チームの取り組みや、 React, TypeScript, GraphQL, Hasura, AWS といった技術スタックについての記事を定期的に発信していきます。よろしければ過去記事や、 もよろしくお願いいたします。

弊社の開発チームでLT会を始めました

WASD Inc. で開発をしている Yutorin です。

今回は弊社の開発チームでLTをする会、通称LT会(COOLな名前募集中)を今年に入ってから始めたらいい感じだった話をします。

LTって何?

Lightning Talksの略で、短いプレゼンテーションのことです。
 

始めた理由

日々の業務で共有しきれないことを全員で周知したり、ディスカッションしてそれぞれの技術力を高めようというのが一番にあります。

加えて、外部のLTなどの発表をする機会に備えた訓練だったり、その際に利用できる資料を日頃からストックしておくという目的もあります。
 

頻度としては隔週です。

毎週金曜日に行っている「Notion会」という書きものをする会と交互に行っています。
30分ほど時間をとっていて、大体一人5分、質疑応答含めて10分となっています。

 

発表している内容

話すことが重要なので、自由に発表してもらっています。
スライド資料を使ってもいいし、Notionに箇条書きして使用してもいいし、口頭だけでもよいです。
気軽に参加できるよう、ハードルは上げすぎないようにするのを心がけています。
 
列挙するとこんな感じです。

読みやすいコードを書こう - Yutorin speakerdeck.com

体に馴染む開発環境 ~ghqはいいぞ~ - shinnoki speakerdeck.com

競プロへの誘 -いざな- - U76NER speakerdeck.com

freeeのサイバー演習シナリオ - mako_jii

プログラミングを勉強したいと言われたら - Yuba https://speakerdeck.com/yuba_4/puroguraminguwomian-qiang-sitaitoyan-waretaraspeakerdeck.com  
開発チームでない人にも自由に参加してもらっています。
Figma Config 2022 - Figmaのコンポ、気持ちよすぎだろ! - dazi_gomi

気になったものがあったらぜひ読んでみてください、併記してあるTwitterアカウントなどから感想をいただけるととても嬉しいです。
 

出席者の声

  • 自分の専門外の話が聴けて楽しい。

  • それぞれの得意なところとか関心のあるところがわかって面白い。

  • 発表後の質疑応答で新しいことを決めることになったり、思わぬ相乗効果がある。

    • 直近では GitHub Discussions を使ってみようみたいなことがありました。
  • 雰囲気が良くてチームの団結力を上げるのに繋がっている。

などなど、良かった感想をたくさん貰えました。
 

おわりに

パンデミックが起きてからエンジニアとしてのキャリアが始まった社員が居ることもあり、イベントなどに参加して発表したことがない人が(自分含め)いました。
そのため、ネタ集めたり実際に作るのはなかなか骨が折れましたが、実際に発表してみるのも楽しく、いい経験が得られていると思います。
 
これからも継続していくので、面白い発表があれば共有したいと思います。


 
WASD TECH BLOG では主に React、TypeScript、GraphQL に関する記事を定期的に発信していきます。
よろしければ他の記事や、 もお願いします。