Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
freeeのエンジニアとReactチュートリアルを学ぼう
Search
kemuridama
December 18, 2024
Programming
0
36
freeeのエンジニアとReactチュートリアルを学ぼう
kemuridama
December 18, 2024
Tweet
Share
More Decks by kemuridama
See All by kemuridama
freee Tech Night がもうすぐ 5 周年を迎える話 / freee Tech Night will soon be 5th anniversary
kemuridama
0
210
会計フロントエンドの TypeScript 化 / Migrating frontend of freee Accounting to TypeScript
kemuridama
0
21k
会計freee が yarn から npm に出戻った本当の理由
kemuridama
12
19k
Other Decks in Programming
See All in Programming
rails newと同時に型を書く
aki19035vc
5
710
非ブラウザランタイムとWeb標準 / Non-Browser Runtimes and Web Standards
petamoriken
0
430
Androidアプリの One Experience リリース
nein37
0
1.2k
情報漏洩させないための設計
kubotak
5
1.3k
CQRS+ES の力を使って効果を感じる / Feel the effects of using the power of CQRS+ES
seike460
PRO
0
240
PHPカンファレンス 2024|共創を加速するための若手の技術挑戦
weddingpark
0
140
Оптимизируем производительность блока Казначейство
lamodatech
0
950
Запуск 1С:УХ в крупном энтерпрайзе: мечта и реальность ПМа
lamodatech
0
950
PicoRubyと暮らす、シェアハウスハック
ryosk7
0
210
functionalなアプローチで動的要素を排除する
ryopeko
1
200
ErdMap: Thinking about a map for Rails applications
makicamel
1
610
LLM Supervised Fine-tuningの理論と実践
datanalyticslabo
8
1.9k
Featured
See All Featured
The Language of Interfaces
destraynor
155
24k
Rails Girls Zürich Keynote
gr2m
94
13k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
29
960
Designing on Purpose - Digital PM Summit 2013
jponch
116
7.1k
Docker and Python
trallard
43
3.2k
The Invisible Side of Design
smashingmag
299
50k
Facilitating Awesome Meetings
lara
51
6.2k
Testing 201, or: Great Expectations
jmmastey
41
7.2k
Why Our Code Smells
bkeepers
PRO
335
57k
The Cost Of JavaScript in 2023
addyosmani
46
7.2k
Thoughts on Productivity
jonyablonski
68
4.4k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
44
9.4k
Transcript
freeeのエンジニアと Reactチュートリアルを学ぼう 2024.12.18
2 メイン業務 - 2018 年新卒 - 2017 年から内定者インターンとして join
- 会計基盤チーム所属 - 主にフロントエンド周り - freee会計の技術的負債の返済 - JavaScript -> TypeScript - 実装の標準化 その他の活動 - freee Tech Night 運営リーダー - Dev Branding / Dev Releationship - freee 技術の⽇運営 - その他 - 社内イベント運営 - 株主総会運営 (~2022) - 社内スタジオ構築 SNS - X (Twitter): @_kemuridama kemuridama フリー株式会社 エンジニア / DevRel Ryo Ochiai プロフィール画像の トリミング⽅法
3 ▼略歴 • 熊本県出⾝ 🏯 • 2022年04⽉1⽇⼊社 ▼業務 •
新卒⼊社してから、ファイルボックスと呼ばれる ファイルストレージ機能をメインで担当 • 現在会計のリアーキテクトを担当するチームで、 機能のマイクロサービス化をやっています! ⾃⼰紹介(@piro) piro フリー株式会社 エンジニア Hiroki Iwashita
4 https://ja.react.dev/learn/tutorial-tic-tac-toe 教材 (React Tutorial)
5 React で◦×ゲームを作ります! 今⽇作るもの
6 • 細かい説明を省くもの ◦ Web サービスの仕組み ◦ HTML/CSS の事前知識
◦ JavaScript の書き⽅ • やらないこと ◦ ローカル開発環境の構築 ◦ タイムトラベルの実装 ◦ TypeScript による開発 やらないこと 全体での説明を省くだけなので 分からないことは恥ずかしがらず 気軽に freee のエンジニアに 聞いてね!
7 普段⾒ている Web サイトはどうやって動いている?
8
9 • Web ページを作成するためのマークアップ⾔語 • 内容を構造化して表現することでブラウザが解釈し Web ページとして表⽰される •
ハイパーリンクを使ってページ同⼠をリンクすることができる HTML (Hypertext Markup Language)
10 • ウェブページのデザインやレイアウトを制御するためのスタイルシート⾔語 • HTML で構造化された Web ページの内容に装飾を加えることができる ◦
⽂字のサイズや⾊を変える ◦ アニメーションを作る CSS (Cascading Style Sheets)
11 • ブラウザ上で動作するプログラミング⾔語 • Web ページを動的に動かすことができる ◦ ユーザがボタンをクリックしたらメッセージを表⽰する JavaScript
(JS)
12 HTML / CSS / JavaScript の 3 つを学べば
最低限 Web サイトを作ることができる!
13 今回のテーマ「Reactチュートリアルを学ぼう」
14 React とは…
15 • UI (User Interface) を作るための JavaScript ライブラリ •
コンポーネントと呼ばれるパーツを実装し、それを組み合わせることで UI を表現する • JSX (JavaScript XML) と呼ばれる HTML のタグっぽいものを組み合わせて構造化する • 仮想 DOM という仕組みを使ってレンダリングの効率化を図っている • freeeでは基本的にフロントエンドには React を採⽤しています React
16 よくわからん……🤔
17 とりあえず動かしてみよう (ここからが React チュートリアル本番)
18 チュートリアルのセットアップ
19 チュートリアルのセットアップ CodeSandbox Web 上でプログラムを書いて実⾏できる 開発環境を提供しているサービス
20 チュートリアルのセットアップ
21 チュートリアルのセットアップ ファイル エディター ブラウザ
22 既にあるファイルを⾒てみよう!
23 • ブラウザが⼀番最初に読む HTML ファイル ◦ どんな Web サイトも基本的には
HTML ファイル public/index.html
24 • ブラウザが最初に読む JavaScript ファイル • 必要な module の読み込みや
div#root に対して component を描画する処理が書かれている src/index.js
25 • ブラウザに表⽰されている×ボタンを表すコンポーネント • src/index.js から読み込まれている src/App.js
26 • ページのスタイルを司るファイル • 基本的な element (HTML タグ) に対するスタイルが書かれている
src/styles.css
27 ブラウザはどうやって表⽰している?
28 • まず public/index.html が読まれる • 次に src/index.js と
src/styles.css が読まれる ◦ ⾃動的に src/index.js を読む命令が HTML に挿⼊されている (⼀旦意識しなくてよい) • 実際のプログラムである src/index.js の処理を追ってみる ブラウザはどうやって表⽰している?
29 src/index.js の処理を追ってみる 外部 module (ライブラリ) の import import
ライブラリや別のファイルに書かれて いる module を読み込むための宣⾔
30 src/index.js の処理を追ってみる 外部 module (ローカルファイル) の import
31 src/index.js の処理を追ってみる div#root に対して component を描画するための root を作成する
document.getElementById() タグに書かれている id 属性を元に element を取得する関数
32 src/index.js の処理を追ってみる root に対して実際に <App> component を描画する StrictMode
開発環境専⽤のバグを発⾒しやすく するための挙動や⾮推奨なコードを 警告してくれるようになる
33 • Square() 関数が宣⾔されている ◦ これ⾃体が React のコンポーネントになる (関数コンポーネント,
functional component) ◦ コンポーネントは関数で書く⽅法の他に class で書く⽅法がある (クラスコンポーネント) • JSX は HTML タグのような書き⽅をするが HTML ではなく JavaScript src/App.js <button> という JSX 要素を 1 つ返している export 他のファイルからその module (今回はコ ンポーネント) を扱えるようにする宣⾔
34 盤⾯の作成
35 3×3 の盤⾯を作りたいので、とりあえずボタンを 9 つ配置したい 最初のゴール
36 改めて src/App.js を⾒てみる ボタンを増やす この button を増やせばボタンを増やすことができそう
37 ボタンを増やす
38 • エラーが出てもとりあえず頑張って読んでみる (英語わからなかったらとりあえず翻訳サービスに⼊れよう) エラー
39 • エラーが出てもとりあえず頑張って読んでみる (英語わからなかったらとりあえず翻訳サービスに⼊れよう) エラー 隣接する JSX 要素は囲みタグで囲む必要があります JSX
フラグメントが必要ですか?
40 • コンポーネントは単⼀の JSX 要素を返す必要があります • 別の複数の JSX 要素を返したい場合は別の
JSX 要素で囲む必要があります エラー 複数の JSX 要素を返してしまっている
41 • 複数の JSX 要素を別の JSX 要素で囲むときにフラグメントという特殊な要素を使います React.Fragment <>
と </> で囲んだことにより 複数の JSX 要素が⼊れ⼦になった 1 つの JSX を返すようになった
42 • エラーは解消されたが、ボタンが横並びになってしまった React.Fragment
43 • 3 × 3 の盤⾯を作るにはボタンを 3 つごと 3
段になるようにする必要がある ◦ <button> を 3 つごと <div> で囲ってあげることで表現する ボタンを 3 つごと段組みする これで 1 段
44 • 期待通り3×3 の盤⾯を作ることができた ボタンを 3 つごと段組みする
45 • 実は <div> や <button> には className という属性
(HTML で⾔う class 属性) ついている ◦ これらは src/styles.css にスタイルが記述されている • JSX では属性のことを Props と呼ぶ スタイルシートを覗く
46 • src/styles.css でスタイルを⾒てみる ◦ ボタンの⼤きさや⽂字サイズなどが設定されている スタイルシートを覗く
47 • 今のままだとすべて「X」なので、1 つ 1 つのボタンに番号を振ります ボタンに番号を振る
48 • それぞれのボタンの「X」を順番に数字に置き換えれば OK ボタンに番号を振る
49 • もともとは 1 つのマス (Square) の意味を持つコンポーネントだった ◦ 今は盤⾯すべて
(Board) の意味を持つコンポーネントに役割が変わった コンポーネントの名前を変える
50 • Square から Board に名前を変更する • プログラミングにおいて、変数や関数の名前にちゃんと意味をもたせることは重要 コンポーネントの名前を変える
Square から Board 名前を変えた
51 • 同じような UI 部品を別のコンポーネントに切り出して再利⽤できるようにしたい Props を通してデータを渡す ⾚枠で囲った部分を共通化できそう
52 • ボタンの部分を新たに Square コンポーネントとして定義する • Board コンポーネントで使うコンポーネントになるので、Board コンポーネントよりも上に定義する
◦ JavaScript は基本的に上からプログラムが評価される 新しい Square コンポーネント
53 • Board コンポーネントから新しく定義した Square コンポーネントを使ってみよう Board から Square
を使う 新しい Square コンポーネント
54 • Square コンポーネントで button の中⾝を「1」と指定したのですべてのボタンが「1」になる Board から Square
を使う
55 • Props と呼ばれる属性を外 (Board コンポーネント) から受け取れるようにする Props を受け取る
value という props を受け取れるようにする 受け取った props を使うようにする
56 • ボタンの中⾝が「value」になっちゃった… Props を受け取る
57 • JSX の中で JavaScript の記法を使うためには波括弧「{}」で囲む必要がある ◦ 今回は value
という変数を JSX 内で使えるように波括弧「{}」で囲む Props を受け取る value を波括弧「{}」で囲った
58 • 中⾝がないボタンが表⽰されるようになる ◦ 現時点で Board コンポーネントから Square コンポーネントに
value を渡していない Props を受け取る
59 • Board コンポーネントから Square コンポーネントに value prop を渡す
Props を渡す value prop としてマスの番号を渡す
60 • 元の状態にもどった ◦ ⾒かけ上変わらなくても、共通化を⾏って変更を楽にするのは⼤切 ◦ 共通化しすぎると逆に変更が⼤変になることもある (難しい) Props
を渡す
61 インタラクティブなコンポーネントの作成
62 • ボタンを押したらコンソール (開発者向けのツール) に「Clicked!」と表⽰されるようにしよう インタラクティブなコンポーネント
63 コンソールを開く ここをクリック
64 コンソールを開く
65 コンソールを開く • コンソールでは JavaScript を実⾏できる ここをクリックするとコンソールをリセットできる
66 ボタンを押したときの処理を実装する • Square コンポーネントで button を押したら console.log() でコンソールに「Clicked!」を出⼒する処理を実装する
クリックされたときに処理を⾏う関数を宣⾔ 宣⾔した関数を onClick prop として渡す
67 ボタンを押してみる • コンソールでは同じ出⼒はまとめられる
68 ボタンを押してみる • コンソールでは同じ出⼒はまとめられる ボタンを押すたびにここの数字が増えていく
69 • 最終的なゴールは◯×ゲームを作ること ◦ マスをクリックしたら「◯」か「×」が表⽰されるようにしたい 本来作りたいものを再度考える Square 内のボタンを押したら「◯」か「×」を表⽰したい Square
コンポーネントでボタンが押されたときに 「◯」か「×」の状態 (state) を記憶しておく必要がある
70 マスを押したら「×」を表⽰する • Board コンポーネントの Square コンポーネント呼び出し部分から value prop
を消す ◦ Square コンポーネントは prop を取らなくなった
71 マスを押したら「×」を表⽰する • useState() を使ってコンポーネント内に状態 (state) を扱えるようにする ◦ useState()
は「初期値」を引数に、返り値として「状態」と「状態を更新するための関数」を配列で返す useState を import する useState() を使って状態を定義 クリックされたときに状態を「X」に変える props を削除
72 マスを押したら「×」を表⽰する • マスを押したら「×」が表⽰されるようになった
73 ゲームを完成させる
74 現在の状況 • Board コンポーネントが Square コンポーネントを 3 ×
3 で描画している • マス (Square コンポーネント) を押したら「×」が表⽰される ◦ Square コンポーネントは状態を持っているが、Board コンポーネントは状態を持っていない ◦ 要するに盤⾯全体の状態を取得することができないため勝者を判定することができない ゲームとして成⽴させるには • Board コンポーネントがすべてのマスの状態を持ち、盤⾯全体の状態を取得できるようにする ◦ ゲームの勝者を判定することが容易になる • Square コンポーネントは親である Board コンポーネントから状態をもらって表⽰するだけでよい 状況の整理
75 Board に状態を持たせる (state のリフトアップ) • ⼦コンポーネントである Square コンポーネントから親である
Board コンポーネントに状態を移動する ◦ これを React チュートリアルでは「state のリフトアップ」と呼んでいる 盤⾯上の 9 つのマスの状態を定義 それぞれのマスの状態を prop として渡してあげる
76 Square から状態を取り除く • Square コンポーネントでは状態を持つ必要がなくなったので削除して props として受け取る •
同様にクリックされたときの処理も Board コンポーネントから渡すので削除して props として受け取る
77 マスが押されたときの処理の実装 • 左上から数えて i 番⽬ (0 始まり) のマスがクリックされたときに
squares[i] に「X」を代⼊して状態を更新する マスがクリック されたときの処理 handleClick(i) を Square に渡す
78 handleClick(i) • 元の squares を破壊しないように slice() で配列をコピーしたうえで状態の更新を⾏う ◦
immutability (不変性) という考え⽅で処理が書かれている 状態をコピーする 配列の i 番⽬に「X」を代⼊する 状態を state に更新する
79 エラー • ブラウザを⾒るとエラーが出ている
80 Board コンポーネントを⾒直す • Square コンポーネントに onSquareClick prop を渡すときに意図せずに関数が実⾏されてしまっている
本来はクリックされたときに関数を実⾏したい
81 Board コンポーネントを⾒直す • onClick には関数を渡す必要があるため「() =>」を前につけて関数として prop を渡してあげる
アロー関数 JavaScript では function キーワー ドを使った関数宣⾔の他に「=>」を 使った関数の宣⾔⽅法がある アロー関数を使って関数として渡してあげる
82 Board コンポーネントを⾒直す • マスを押したら「×」が表⽰されるようになった (元の状態に戻った)
83 ⼿番の処理
84 ◯と×を交互に打てるようにする • ◯×ゲームとして成り⽴たせるためには×だけマスに⼊⼒できるだけでは⾜りない • ◯と×のどちらのプレイヤーの番なのかを状態として持つ必要がある
85 ◯と×を交互に打てるようにする • useState() を使って現在が×の番なのか否かを boolean として状態を定義してあげる ×が次の番なのか否かを表す状態を定義 マスがクリックされたとき
×の番だったら×、 それ以外のときは◯を 状態として保存する ⼿番を逆転する
86 ◯と×を交互に打てるようにする • ◯と×が交互に打てるようになった ◦ が、すでにマスに◯か×がある状態でもクリックしてマスを上書きできてしまう…
87 バグを修正する • squares[i] に◯か×が⼊っている場合 (要するに null ではない場合) は
handleClick(i) の処理を中断する ◦ 関数の処理を早い段階で切り上げる早期リターンと呼ばれる⼿法を使う すでに squares[i] に値が⼊ってる場合は return する
88 バグを修正する • すでに⼊⼒された◯や×を上書きできなくなった!
89 勝者の宣⾔
90 ◯と×ゲームの勝者とは • たて‧よこ‧ななめのどれかがすべて⾃分のマークになっていたら勝ちとなる 0 1 2 3 4
5 6 7 8 たて • 0, 3, 6 • 1, 4, 7 • 2, 5, 8 よこ • 0, 1, 2 • 3, 4, 5 • 6, 7, 8 ななめ • 0, 4, 8 • 2, 4, 6 squares の中⾝を それぞれの勝利パターンで調べて、 すべての要素が◯か×の どちらかだったら、 そのプレイヤーの勝利と判定する
91 勝者の判定ロジックの実装 • Board 内の状態 squares を引数にそれぞれの勝利パターンを順番にチェックしていく ◦ 勝者が決まったら◯か×のどちらかを返り値として返し、勝者が決まらない場合は
null を返す 勝利パターン それぞれのパターンで 要素の中⾝がすべて⼀致したら その値を返す
92 勝者の判定ロジックの実装 • 勝者が決まった時点で⼿番を回す必要がなくなる ◦ Board 内の handleClick(i) で勝者を判定し、勝者が決まった時点でゲームの進⾏を⽌める
勝利が決まったら早期 return
93 あと⼀歩
94 ゲームの状態を表⽰する • 次のプレイヤーがどちらなのか、勝者が決まったのかなどゲームの状態を画⾯上に表⽰しましょう 勝者が決まった場合勝者を表⽰ それ以外はどちらの⼿番か表⽰する
95 完成! • どちらが⼿番なのか表⽰され、ゲームが進⾏し決着が付くと勝者が表⽰されるようになった
96 お疲れ様でした!
97 React Tutorial を最後まで完了する • タイムトラベルの追加 より快適な開発環境へ • ローカル開発環境を構築する
• TypeScript を導⼊する ⾒た⽬にこだわる • CSS などによる装飾を加える React Deepdive • React Hooks とは • React と jQuery の違い After work 今後は何を学ぶといい?など ⼩さな悩みでも ぜひ相談してください!
98 今後も⼀緒に学習しませんか? 「freee Tech community for Students」を開設します!!!! • どんなコミュニティ?
◦ 学⽣が安⼼してweb開発、プログラミングを学習できるコミュニティです。 ◦ (ベータ版ですので、どんなコミュニティにするか?⼀緒に考えてくれる⽅も 募集中!) • 何ができるの?? ◦ freeeのエンジニアや学⽣同⼠で学びの共有や困りごとの相談ができます ◦ ⼀緒に学習できる仲間も⾒つけていただけます ◦ 不定期でコミュニティ限定のイベントも開催予定です • どこでやるの?? ◦ slackです! • どうやって参加するの? ◦ QRコードからお申し込みください!
スモールビジネスを、世界の主役に。