Reactの公式ページのMAIN CONCEPT
がReact知るのの立ち上げに非常に役立ったので、
各章のポイントを自分なりにメモ
https://ja.reactjs.org/docs/hello-world.html
Hello World
特になし
JSX の導入
- JSXを使う理由
-
表示のためのロジックは、イベントへの応答や経時的な状態の変化、画面表示のためのデータを準備する方法といった、他の UI ロジックと本質的に結合したものであり、React はその事実を受け入れます。
-
マークアップとロジックを別々のファイルに書いて人為的に技術を分離するのではなく、React はマークアップとロジックを両方含む疎結合の「コンポーネント」という単位を用いて関心を分離します。
-
- JSXはインジェクション攻撃をふせぐ
要素のレンダー
-
ReactDOM.render(element, document.getElementById('root'));
index.jsとかに書くルートノードの記述 - setStateでstateが更新されると良きにReactが、
ReactDOM.render
を呼んでUIが更新される - ReactDOMは要素とその子要素を以前のものと比較し、変更が必要な部分だけの更新を行う
コンポーネントと props
- React コンポーネントクラスを定義するには、
React.Component
を継承する-
render()
は必ず定義が必要 - コンポーネントのライフサイクルに応じて様々なメソッドが呼び出される。詳細は↓
https://ja.reactjs.org/docs/react-component.html
-
-
<Welcome name="Sara" />
Welcomeコンポーネントに、引数nameに値Saraを渡している - Welcomeコンポーネントでは、
this.props.name
で引数の値をとれる - propsは変更してはいけない
state とライフサイクル
- state を直接変更しないこと
-
setState()
で更新しないとrender()
呼び出されない - stateの初期値はコンストラクタで指定する
-
-
this.props
とthis.state
はReactが効率的なタイミングで非同期に更新される- stateの値をインクリメントしたり同期が必要な場合は
setState()
に関数を渡して更新する- ダメな例
this.setState({counter: this.state.counter + this.propsincrement,});
- 良い例(アロー関数渡し)
this.setState((state, props) => ({counter: state.counter + props.increment}));
- ダメな例
- stateの値をインクリメントしたり同期が必要な場合は
- stateに複数の変数がある場合、更新したい変数だけ
setState()
すればよい - 親子のコンポーネント間で値を共有したい場合は、
state のリフトアップ
の章を参照
イベント処理
- JSX ではイベントハンドラとして文字列ではなく関数を渡します
handleClick関数を別途定義して↓のように書く
<a href="#" onClick={handleClick}>
- 関数の引数で
e
を定義し、イベントを操作できる
https://ja.reactjs.org/docs/events.html - JavaScript では、クラスのメソッドはデフォルトではバインドされないので、使用する関数をbindする必要がある
- 関数をクラスフィールド定義するのが、パフォーマンス的にも良い
handleClick = () => {console.log('this is:', this);}
- 関数をクラスフィールド定義するのが、パフォーマンス的にも良い
- クラスフィールド定義で関数に引数を渡すなら↓のように書く
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
条件付きレンダー
- JSXの中で
{}
で囲んだ式を利用して、条件分岐できる-
{list.length > 0 && <h2>listの数は{list.length}です</h2>}
のようにJavaScript の論理 && 演算子を利用して表示・非表示できる -
{this.state.showWarning ? 'Hide' : 'Show'}
のようにJavaScript の condition ? true : false 条件演算子を利用して、出力値を変更できる
-
- コンポーネントを非表示したい場合は、
render()
でreturn null;
する
リストと key
- ↓のようにJSX内でaccounts文
<li>
を出力できる
<ul className=" list-unstyled" id="List">
{accounts.map((account, index) => (
<li key={account.name}>{account.name}</li>
))}
</ul>
-
<li>
に一意なkey
属性の指定は必須 -
key
は、どの要素が変更、追加もしくは削除されたのかを React が識別する - 要素の並び順が変更される可能性がある場合、indexを
key
として使用すべきでない
(並び順変更なくても、key
はindex以外を指定した方が良いと思う)
フォーム
- フォームの入力値はstateで扱うようにする
- stateの値をvalue属性に設定し、onChangeイベントの関数内で
setState
する
<input type="text" value={this.state.value} onChange={this.handleChange} />
- stateの値をvalue属性に設定し、onChangeイベントの関数内で
- input、textarea、selectは特にやり方を確認しておく
state のリフトアップ
- stateを変更できるのは自コンポーネントだけ
- 呼び出し元や呼び出し先のコンポーネントが直接変更はできない
- 呼び出し先のコンポーネントが呼び出し元のstateを変えたければ、
setState()
を含んだ関数を子コンポーネントに渡して、子コンポーネントが渡された関数を実行して更新する
- のっている事例に従って動きを確認しておく
コンポジション vs 継承
-
{props.children}
でコンポーネントのタグ内に記載した要素をコンポーネントに受け渡せる - Classの継承は使うべきではない
React の流儀
Reactで開発する際のStepを説明しています
- Step 1: UI をコンポーネントの階層構造に落とし込む
- UIから、コンポーネントを抽出します
- コンポーネントの抽出は単一責任の原則 (single responsibility principle) に沿うとよい
(細かすぎると、今度は別の弊害が起きるので、適度にが良いのかなと)
- Step 2: Reactで静的なバージョンを作成する
- stateを使うと複雑になるので、まずデータモデルを描画するだけの静的なバージョンを作る
- 各コンポーネントと、呼び出し元から呼び出し先のコンポーネント間のpropsを定義していく
- Step 3: UI 状態を表現する必要かつ十分な state を決定する
- stateにするものを洗い出す
- 下記3点を意識する
- 親から props を通じて与えられたデータでしょうか? もしそうなら、それは state ではありません
- 時間経過で変化しないままでいるデータでしょうか? もしそうなら、それは state ではありません
- コンポーネント内にある他の props や state を使って算出可能なデータでしょうか? もしそうなら、それは state ではありません
- Step 4: state をどこに配置するべきなのかを明確にする
- 洗い出したstateをどのコンポーネントで扱うべきか決め、stateの変更処理をいれる
- Step 5: 逆方向のデータフローを追加する
- 呼び出し先のコンポーネントで、呼び出し元のstateを変更する処理をいれる