【React】なぜReduxを使うのか
Reactでよく一緒に使われるらしい「Resux」というフレームワークについて、今日勉強してきたころをまとめます。
1. Reduxとは
stateを管理するフレームワークのこと。
React以外にも、Angularなど他のJavaScriptライブラリとも一緒に使うことができるらしいです。
2. React + Redux の利点
Reactはコンポーネント間でデータを受け渡しをするときに、Propsを介して受け渡します。
Reactの特徴に「Data Flow」といって、データを単方向にデータバインディングするというものがあります。
例えば、コンポーネントGを表示するのに、コンポーネントAが持っているデータが必要な場合、下図のように間のコンポーネントBとEを通ってデータを渡していかないといけません。
このように、コンポーネントのネストが深くなったり横に広がるほど、データの受け渡し回数が増えて大変です。
そこで、Redux を使うとすべてのデータを Store というもので1箇所で管理できるようになります。
先ほどの例だと、どのコンポーネントも必要なデータはStoreから必要なデータを受け渡しできるようになり、素のReactのように欲しいデータをどのコンポーネントから流してこないといけのかを考えなくてよくなります。
3. まとめ
とりあえず、今日理解したReduxを使うと何がいいのかまで書いてみました。
これから詳細なところまで手を動かしながら勉強していこうと思います。
広木大地「エンジニアリング組織論への招待」
「エンジニアリング組織論への招待」という本を読んだので、その読書備忘録です。
【書籍情報】
エンジニアリング組織論への招待
著者:広木大地
発行:技術評論社
総括
不確実性への向き合い方を、
「個人」「上司・部下(メンター・メンティ)」「チーム」「組織」
の観点で説明している。
不確実性=わからないこと
わからないことと向き合うには勇気がいる。
不確実なことでも「見る」ことができるようになれば対処しようがある。
「いかにして不確実なものを見える化して管理するのか」が大切だということを全体を通して伝えているのだと思う。
自身をメンタリングする方法から、メンターとしてメンティをメンタリングするための手法やコミュニケーションの取り方も多く紹介されている。
自分も今後輩2人とともに仕事しているが、「そうなんだよねぇ」とか「こうすればいいのか」など発見が多かった。
何かを説明したときに「わかった?」ときいて「わかりました。」と答えられる流れ。
これは意味のないやり取りだということも、経験から納得。
「試しに少しやってみてもらう」とか「自分の言葉で説明してもらう」などして、本当に理解してくれたのか確認が重要。
アジャイル開発についても触れている。
自分はいままでの業務で計画駆動型の開発しかしてこなかった。
もし、今自社サービスのような継続的に発展させることが必要なものを作ろうと思ったら、アジャイル開発前提でないとサービスのリリースにもたどりつけないと感じた。
計画駆動型の開発でやっていたら、リリースできたとしてもその時には「ニーズがなくなっている」 or 「他社が同じサービスを先に出している」かもしれない。
計画駆動型の開発ではマーケットの変化についていくことはできないだろうな。
まとめ
自分がいままであまり触れたりしてこなった分野の内容だったなと思いました。
メンタリングの方法とか、不確実性の削減方法など、業務でも「あぁ、あるなぁ」「そうすればよかったのか」といった発見もあり、読んでよかった一冊でした。
1回読んだだけど実践までに結びつくか微妙なので、また読み返しそうです。
【JavaScript】変数宣言時の var, let, const
Reactでは従来(ES2015(ES6)より前)のJavaScriptでも書けるらしいのですが、標準はES2015(ES6)だそうです。そして、JavaScriptの現在の最新はES2019(ES10) だそうです。
でも、Reactで調べると出てくるのはES2015(ES6)(以降、ES6)。最低限、ES6に則った形で作りなさいよってっことかな?
Reactを勉強するにあたってJavaScrip知識必須なので、JavaScriptの基本を押さえつつ、ES6で追加された機能や構文についても勉強していきます。
今回は let と const 、varについて。
1. let , const, var
従来(ES6よりまえ)であれば変数宣言時には var を使っていました。
ES6以降では、変数・関数の宣言に let と const というのが追加されました。
(関数についてはまた次回)
var, let, const の違いをみていきます。
var での変数宣言
下記ではグローバル変数とローカル変数それぞれ宣言して、console.logで各値を表示させています。
関数fooの外で宣言されている 「var y」と、関数foo内の「var y」は変数名は同じですが、スコープが異なっているので別の変数として扱われます。
また、関数foo内の 「var y」 のように同一スコープ内で同じ変数名を宣言しても、エラーにはなりません。
var x = 10; var y = 20; function foo() { x = 15; var y = 25; console.log('x=' + x); console.log('y=' + y); var y = 1; console.log('y=' + y); } foo(); console.log('x=' + x); console.log('y=' + y); #結果 x=15 y=25 y=1 x=15 y=20
var は変数が制御構文内で宣言されていても、外からアクセスすることが可能です。
下記のようにif文の中で変数を宣言しても、if文のスコープ外からその変数にアクセスができています。
Java言語などではコンパイルエラーになる書き方なので、ちょっと違和感。。。
if(true) { var hello = 'こんにちは'; } console.log(hello); #結果 こんにちわ
let での変数宣言
var のときと同様にグローバル変数とローカル変数それぞれ宣言して、console.logで各値を表示させています。
var とは異なりSyntaxErrorとなります。
これは let で変数を宣言した場合、変数の再宣言が不可能だからです。
そのため、関数fooの中で 「let y = 25;」 と変数 y を宣言したのち、「let y = 1;」 と変数 y を再宣言しているためにエラーとなります。
let x = 10; let y = 20; function foo() { x = 15; let y = 25; console.log('x=' + x); console.log('y=' + y); let y = 1; console.log('y=' + y); } foo(); console.log('x=' + x); console.log('y=' + y); #結果 Uncaught SyntaxError: Identifier 'y' has already been declared
また、有効スコープについても差異があります。
下記のようif文の中で変数宣言した場合、var であればスコープ外からもアクセスできました。しかし、let の場合はReferenceErrorとなり、制御構文のスコープ外から参照することができません。
if(true) { let hello = 'こんにちは'; } console.log(hello); #結果 let_if.html:10 Uncaught ReferenceError: hello is not defined
const での変数宣言
const は、let と同様に変数の再宣言が不可能です。
それに加えて、変数への値の再代入も不可能となっています。
要するに、const は定数の宣言です。
下記の例だと 「const x = 10;」とconst で 変数 x を宣言&初期化したのち、関数foo()の中で変数 x に対して、"15" を再代入しています。
その結果、「定数変数への割り当てしてるからTypeErrorだよ」っていうエラーが出ています。
const x = 10; const y = 20; function foo() { x = 15; } foo(); console.log('x=' + x); console.log('y=' + y); #結果 const.html:10 Uncaught TypeError: Assignment to constant variable.
2. まとめ
変数宣言につかわれる、var, let, const についてまとめてみました。
JavaScriptをまともに書いたのが去年の業務で約3か月ぐらい。まだまだ初心者ですが、Reactと並行して勉強していきます。
【React】チュートリアル その2
今回はチュートリアルで作成していた「三目並べ」の続き。
「タイムトラベル機能の追加 」を実装したので、その振り返りです。
チュートリアルで作成できる三目並べは下記リンクから実際に遊べます。
https://codepen.io/gaearon/pen/gWWZgR?editors=0010
【目次】
1. Game基盤クラス
三目並べの盤面やゲームの進行状況を管理している、メインとなるクラス。
class Game extends React.Component { ・・・ }
1.1. コンストラクタ【constructor】
constructor(props) { super(props); this.state = { history : [{ squares: Array(9).fill(null), }], stepNumber: 0, xIsNext: true, } }
Gameコンポーネントの初期stateを3つ、コンストラクタ内でセットしています。
【history】
「nullで初期化されたサイズが9の配列squares」の配列。
三目並べの手番の履歴を管理する。
【stepNumber】
現在、何手目の状態なのかを管理する。
【xIsNext】
プレーヤーの手番を管理する。
1.2. マス目ボタンのクリックイベント【handleClick】
1.2.1. 最新の盤面情報を取得
handleClick(i) { const history = this.state.history.slice(0, this.state.stepNumber + 1); const current = history[history.length - 1]; const squares = current.squares.slice(); ・・・ }
【history】
history stateの配列の先頭から、「stepNumber state + 1」までの要素を取得。
例えば、stepNumber stateが "3"の場合、history state配列の1番目(インデックス "0")から、4(=3+1)番目(インデックス "3")までの要素を取得する。
【current】
上記で取得したhistoryから、最新の盤面情報を取得。
【squares】
現在の盤面の状態の各マス目を取得。
1.2.2. 盤面の情報を更新するか判定
・・・ if (calculateWinner(squares) || squares[i]) { return; } ・・・ }
勝敗がすでについている、もしくはクリックしたマスが既に埋まっている場合は何もせずにreturnする。
1.2.3. stateを更新
・・・ squares[i] = this.state.xIsNext ? 'X' : 'O'; this.setState({ history: history.concat([{squares: squares, }]), stepNumber: history.length, xIsNext: !this.state.xIsNext, }); }
最新のマス目情報「squares」のクリックされたマス目に、手番により"X" or "O"を代入。
「setState()」でコンポーネントのstateを更新し、画面を再描画する。
1.3. 過去の手番に戻る【jumpTo】
jumpTo(step) { this.setState({ stepNumber: step, xIsNext: (step % 2) === 0, }); }
引数の「step」番目の手番まで、コンポーネントのstateを更新&画面の再描画を行う。
1.4. レンダー関数【render】
stateが更新されるたびにrender関数が呼ばれ、画面が再描画されます。
1.4.1. 現在の手番や勝敗を取得
render() { const history = this.state.history; const current = history[this.state.stepNumber]; const winner = calculateWinner(current.squares); ・・・ }
【history】
history stateを取得しています。
【current 】
上記で取得した「this.state.history」のうち、現在の盤面情報を取得しています。
【winner 】
前回説明した「calculateWinner」関数を呼び出し、勝敗を取得します。
1.4.2. 過去の手番に戻ることのできるボタンを生成
render() { ・・・ const moves = history.map((step, move) => { const desc = move ? 'Go to move #' + move : 'Go to game start'; return ( <li key={move}> <button onClick={() => this.jumpTo(move)}> {desc} </button> </li> ); }); ・・・ }
moves は、過去の手番に戻る(ジャンプする)ことのできるボタン一覧を描画するためのReact要素。
mapメソッドを使ってhistory配列の各要素(手番)について、
* ボタンに表示させる文字列React要素「desc 」を生成
* リスト要素でボタンを1行描画するJSXを「move」へ返している。
「jumpTo()」は後程説明します。
【Reactのリストについて】
Reactでリストを描画する際は「key」を割り当てる必要があります。
Reactはリストが変更された場合、どこが変更されたのかを知る必要があります。
(仮想DOMにより差分のみを更新するため)
そのため、リストの各項目を区別できるように、keyプロパティを割り当ててあげます。
リストが再描画されるときは、Reactはリストの各項目のkeyについて、前回(再描画前)のリスト項目内に同じkeyを持つものがないか探します。
前回リストに存在しないKeyが含まれていた場合
⇒コンポーネントを作成前回のリストにあったkeyが新しいリストに存在しない場合
⇒以前のコンポーネントを破棄前回リストのkeyとマッチするものが存在した場合
⇒対応するコンポーネントを移動
1.4.3. 現在の状況を判定
render() { ・・・ let status; if (winner) { status = 'Winner: ' + winner; } else { status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O'); } ・・・ }
勝負がついているのか、ついていない場合は現在どちらの手番なのかを変数「status」に文字列として保持します。
1.4.4. JSXをreturnする
render() { ・・・ return ( <div className="game"> <div className="game-board"> <Board squares = {current.squares} onClick = {(i) => this.handleClick(i)} /> </div> <div className="game-info"> <div>{status}</div> <ol>{moves}</ol> </div> </div> ); }
「className="game-board"」のdiv要素では、Boardコンポーネントを描画します。
Boardコンポーネントには、現在の盤面の状況と、盤面のマス目ボタンが押されたときに呼び出されるメソッドをpropsとして渡しています。
「className="game-info"」div要素では、
「1.4.3. 現在の状況を判定」で作成した文字列変数「status」と、
「1.4.2. 過去の手番に戻ることのできるボタンを生成」で生成したReact要素「move」のJSXを、「ol」タグで囲むことで項番付きリストとしてボタンを描画しています。
2. 盤面クラス
三目並べの盤面を描画するクラス。
class Board extends React.Component { ・・・ }
2.1. マス目描画【renderSquare】
renderSquare(i) { return ( <Square value={this.props.squares[i]} onClick={() => this.props.onClick(i)} /> ); }
「Square」関数コンポーネントをreturnしています。
「Square」関数コンポーネントへは、Gameコンポーネントから渡されたprops内の最新の盤面情報のi番目のマス目と、onClickメソッド(GameコンポーネントのhandleClick()メソッド)をpropsとして渡しています。
2.2. レンダー関数【render】
render() { return ( <div> <div className="board-row"> {this.renderSquare(0)} {this.renderSquare(1)} {this.renderSquare(2)} </div> <div className="board-row"> {this.renderSquare(3)} {this.renderSquare(4)} {this.renderSquare(5)} </div> <div className="board-row"> {this.renderSquare(6)} {this.renderSquare(7)} {this.renderSquare(8)} </div> </div> ); }
盤面の各マス目を3×3になるように「renderSquare(i)」で描画しています。
3. マス目ボタンの関数コンポーネント
function Square(props) { return ( <button className="square" onClick={props.onClick}> {props.value} </button> ); }
引数はBoardコンポーネントから渡されたpropsです。
盤面のマス目をボタンとして描画するためのJSXをreturnしています。
マス目ボタンがクリックされたときには、onClickイベントに指定されている「GameコンポーネントのhandleClickメソッド」が呼び出されます。
4. まとめ
React公式のチュートリアルを一通り実施し、そのコードを備忘録的に解説しました。
自分の認識間違いなどあるかもしれませんが、まだ初心者のためご容赦ください(-_-メ)
【React】JSXの導入
Reactのチュートリアルを読み始めたので、大事だと思うところをまとめてきます。 今日は「JSX」。
【目次】
- 1. JSX(JavaScript eXtension)とは
- 2. JSXを使う理由
- 3. JSX に式を埋め込む
- 4. JSX で属性を指定する
- 5. JSX はインジェクション攻撃を防ぐ
- 6. まとめ
1. JSX(JavaScript eXtension)とは
Reactでは、JSXというJavaScriptの構文を拡張したものが使われる。
const element = <h1>Hello, world!</h1>;
マークアップを書いているように思うが、これはJavaScriptを書いている。
2. JSXを使う理由
Reactのチュートリアルには下記のよう書いてあります。
マークアップとロジックを別々のファイルに書いて人為的に技術を分離するのではなく、React はマークアップとロジックを両方含む疎結合の「コンポーネント」という単位を用いて関心を分離します。
下記のShowUserNameというコンポーネントで考えてみる。
class ShowUserName extends React.Component { constructor(props) { super(props); this.state = { firstName: 'Harper', lastName: 'Perez', } } // JSXで書かれたマークアップ? render() { return ( <div> <h1> Hello, {formatName(user)} </h1> </div> ); } // ロジック formatName(user) { return this.state.firstName + ' ' + this.state.lastName; } }
マークアップとロジックを両方含んだ疎結合の「コンポーネント」
⇒ShowUserName
関心の分離
⇒コンポーネント内で
・マークアップ(render())と
・ロジック(formatName(user) )
がそれぞれ分離されてるってことかな?
上記のような理由で、Reactでは基本的にはJSXを使うらしいです。
あと、JSXはJavaScriptだから
エラーや警告をコンパイル時に確認できる
⇒デバッグしやすい
ってのがメリットだということだと思う。
3. JSX に式を埋め込む
JSXではJavaScriptの式を中括弧{}で囲むことで使用できる。
変数
const name = 'Taro Yamada'; const msg = <h1>Hello, {name}</h1>;
計算式
const add = <h1>3 + 7 = {3 + 7}</h1>;
関数
const name = ( <h1> Hello, {formatName(user)} ! <h1> ) formatName(user) { return this.state.firstName + ' ' + this.state.lastName; }
JSXの式は、コンパイル後にはJavaScriptオブジェクトとして評価される。
よって、if文などの条件式だったり、変数の代入だったり、関数の引数や戻り値にも使うことができる。
function getGreeting(user) { if (user) { return <h1>Hello, {formatName(user)}!</h1>; } return <h1>Hello, Stranger.</h1>; }
4. JSX で属性を指定する
マークアップの属性に文字列リテラルを指定することや、属性にJavaScript式を埋め込むこともできる。
属性に文字列リテラルを指定する
const element = <font color="red">Hi, React!</font>;
属性にJavaScript式を埋め込む
const element = <img src={user.avatarUrl}></img>;
ただし、属性にJavaScript式を埋め込むときに、中括弧を囲む引用符を書いてはいけないらしい。
こんなのかな?
const iro= 'red'; const element = <font color="{iro}">Hi, React!</font>;
5. JSX はインジェクション攻撃を防ぐ
デフォルトのReact DOMではJSXに埋め込まれた値をレンダリングされる前にエスケープするらしいです。
悪意あるユーザーが不正なコードを埋め込もうとしても、入力値を一度JSXに代入するようにしておけば、実行可能な不正コードがHTMLに埋め込まれることを防ぐことができるということ。
(HTMLにレンダリングされるときに、JSXに代入された不正なコードはエスケープされてすべて文字列に変換される。)
つまり、JSXを使うとXSS (cross-site-scripting) を防ぐことができるということ。
6. まとめ
自分が大事だと思ったところをまとめてみました。
SPA (Single Page Application)
今日はSPA (Single Page Application)について
1. SPA (Single Page Application)とは
SPAは1つのWebページで構成されるWebアプリケーションのこと。
SPAではJavaScriptでページ内のHTMLを差し替える(書き換える)ことによって、ページの更新を行います。
SPAでは幅広いUIを実装することができるため、ネイティブアプリの代わりとしても使うことが可能です。Webブラウザで動作するため、OSに依存しないというメリットもあります。
1.1. 従来のWebアプリの動き
従来のWebアプリでは、
1. ユーザーがアクション(ボタンを押したり、リンクをクリックしたり)を起こす
2. ブラウザからサーバーへリクエストを送信
3. サーバーはリクエストに応じたWebページ(HTML/CSS/JavaScriptなど)のレスポンスを送信
4. ブラウザはレスポンスを受け取って画面全体を更新
という流れで画面の更新が行われる。
ボタンのクリックなどでページ遷移が行われるたびにページ全体の更新が行われることになります。
1.2. SPAのWebアプリの動き
従来のWebアプリに対してSPAでは、
1. ユーザがアクションを起こす
2. アクションに対して必要なデータのみをサーバーにリクエスト
3. サーバーはリクエストに応じたデータをJSON形式のデータでレスポンスを送信
4. ブラウザはレスポンスを受け取って、ページ内の必要な箇所のみを更新
という流れで画面の更新が行われる。
SPAではページ内の必要な箇所のみを更新すればよく、ユーザーがアクションを起こすたびにページ全体を更新する必要がない。よって、従来のWebアプリよりも応答性が良くなります。
2. SPAで使われている技術
2.1. フロントエンド
SPAのフロントエンドではJavaScriptをそのまま使うのではなく、JavaScriptフレームワークやライブラリ(AngularやVue.js、Reactなど)を使用するのが一般的です。
2.2. 通信
クライアントとサーバーの通信にはAjaxやWebSocketなどを使用して非同期通信を行います。
2.3. バックエンド
バックエンドはRuby on RailsやJava、ASP.NETなどいろいろ選択肢はあり、Web APIとしてクライアントに機能を提供するのが一般的です。
そのほか、Node.jsを使用してバックエンドもJavaScriptで記述する方法もあります。Node.jsはサーバサイドで動作するJavaScriptの実行環境です。
3. まとめ
ReactでWebアプリを作るために勉強中なので、SPAについても調べてまとめてみました。
HHKBがフルモデルチェンジしたらしいよ
とうとう、、、
とうとう発表されました。
HHKB(Happy Hacking Keyboard)のNewモデル!!
自分も仕事で愛用しているHHKB。モデルチェンジで何が変わったのか気になります。
ということで、今日はモデルチェンジしたHHKBについて紹介します。
【目次】
ラインアップ
今回発表されたHHKBは大きく分けて3種類。
- HHKB Professional HYBRID Type-S
- HHKB Professional HYBRID
- HHKB Professional Classic
HYBRID
HYBRIDモデルではBluetooth接続とUSB接続が可能なマルチプラットフォーム対応。
USB接続はUSB Type-Cを採用。ケーブル挿すときに端子の上下を気にする必要もなし。
BluetoothはVer4.2になり、通信の安定性や、消費電力の改善が期待されます。
また、Bluetooth接続のマルチペアリング(最大4台まで登録可)ができるようになり、切り替えを簡単なキー操作でできるそうです。
Classic
ClassicモデルはHHKB Professional 2のリプレースモデル。インターフェースはUSB Type-Cのみとなります。
HHKB Professional HYBRID Type-S
HHKBの最上位モデル。
HYBRID Type-S には下記3モデル各2色が存在します。
Type-S仕様の静音仕様はもちろんのこと、DIPスイッチによるキー配列のカスタマイズ機能以外に、専用アプリによるキーマップの変更もできるらしいです。
※キーマップ変更はWindowsでのみ動作。
HHKB Professional HYBRID
HHKBの中位モデル。
HYBRID にもHYBRID Type-S 同様に下記3モデル各2色が存在します。
基本的にはHYBRID Type-Sと同じ仕様。
違うのは静音仕様が省かれている点のみ。
前モデルの時もType-Sと、そうでないモデルは打鍵感が結構異なっていました。実際に実機を触ってみて、好みの方を選ぶのがいいと思います。
HHKB Professional Classic
HHKBのエントリーモデル。
Classic には下記2モデル各2色が存在します。
Classicモデルは
・Bluetoothが非対応
・キーマップ変更機能が非対応
・日本語配列モデルが存在しない
となっています。
このように非対応な機能がある分、価格は3グレードの中で一番安くなっています。
まとめ
本日発表されたHHKBのNewモデルについて紹介しました。
現在持っているHHKBは会社で使ってるので、家用に欲しいなぁと思ったり。
やっぱり、一番気になるのは、HHKB Professional HYBRID Type-Sの日本語配列モデル。
価格は税込 35,200円・・・
気軽にポチるには躊躇する価格なので、まずは店頭で実機を触ってこようと思います。
最後に、この記事を読んでNew HHKBを欲しいと思ったあなた!
今ならPFUダイレクトで購入すると先着3,000名様に「キーボードルーフ」がもらえるらしいですよ。
いつ買うの??買うなら今でしょ!
(なんか宣伝風になってしまった(;゚Д゚))