0から始まるReactのお勉強
こんにちは。とある大学3年生です。インターンでReactを使うとのことで0から勉強した際にまとめたものです。誰かのためになれたら幸いです^^
概要
Reactとは
ユーザーのインターフェースを構築するための宣言型で効率的なJSのライブラリ
複雑なUIを「コンポーネント」と呼ばれる小さく独立した部品から組み立てられる。
class ShoppingList extends React.Component {
render() {
return (
<div className="shopping-list">
<h1>Shopping List for {this.props.name}</h1>
<ul>
<li>natto</li>
<li>daikon</li>
<li>osakana</li>
</ul>
</div>
);
}
// Example usage: <ShoppingList name="Mark" />
shoppingListはReactコンポーネントクラス、もしくはReactコンポーネント型
コンポーネントはprops(properties)とよばれるパラメータをうけとってrenderメソッドを通じて表示する階層構造を返す
state:コンポーネントに何かを覚えさせること
Reactコンポーネントはコンストラクタでthis.stateを設定することで状態を持つことができる
子要素同士でやりとりしたりする際に親要素がstateで状態を保存し、親を介してやり取りさせる
props:親から子へ渡すことでアプリ内の情報のやりとりをする
リファクタリング:ソフトウェアの挙動を変えない範囲で内部構造を整理すること
親要素のコンポーネントが全子要素の状態を保持し、子要素が何を表示するべきかpropsを渡すことで伝える。
このように値を伝えられるだけの子要素(コンポーネント)を制御されたコンポーネントという。
supet()props:JSのクラスではサブクラスのコンストラクタを定義する際にsuperを呼ぶ必要がある。
変化する値へのアプローチ(二種類)
①データの値を直接いじってデータをミューテート(書き換え)する
②望む変更を加えた新しいデータのコピーで古いデータを置き換える←イミュータビリティ
イミュータビリティの利点
①複雑な機能が簡単に実装できる
直接的にデータのミューテートを避けることでゲーム以前のヒストリ(履歴)をそのまま保ってあとで利用できる
②変更の検出
ミュータブルなオブジェクトの中身が直接書き換えられるため変更が検出できない。イミュータブルであると以前のコピーと比較してオブジェクトツリー全体を走査できる
③Reactの再レンダータイミングの決定
Reactでpure componentを構築しやすくなる。コンポーネントをいつ再レンダーすべきか決定しやすい
関数のコンポーネント
関数コンポーネントとは
自分のstateを持たず、renderメソッドだけを有するコンポーネントをよりシンプルに描くための方法。
React.componentを継承するクラスを定義せず、引数をpropsとした関数を書くことができる
関数を基本的に使う。
ex)クラスコンポーネントを関数コンポーネントに変更する
クラスコンポーネント
class Arasuka extends React.Component {
render() {
return (
<button
className="arasuka"
onClick={() => this.props.onClick()}
>
{this.props.value}
</button>
);
}
}
↓
関数コンポーネント
function Arasuka(props) {
return (
<button className="arasuka" onClick={props.onClick}>
{props.value}
</button>
);
}
フォーム
HTMLのフォーム
→ユーザーがフォームにデータを送信したと同時にページが遷移する
制御されたコンポーネント :フォームの送信に応答してフォーム内のデータにアクセスする関数を動かすことができる
stateに更新されうる情報を保存、setstateで更新する。
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
制御されたコンポーネントを使うと、ユーザ入力の値は常に React の state によって制御されるようになります。これによりタイプするコード量は少し増えますが、その値を他の UI 要素に渡したり、他のイベントハンドラからリセットしたりできるようになります
React.FCってなに?
関数コンポーネントの型
メモ化
計算結果を保持し、それを再利用すること
「メモ化する」=「計算結果を再利用できるように保持する」
「メモ化された値」=「計算結果が保持された値」
UseMemo
メモ化された値を返すフック
なぜメモ化された値をつかうのか
値の不要な計算をスキップすることでパフォーマンスの向上につなげる
UseMemo構文
useMemo(() => 値を計算するロジック, 依存配列);
依存配列:値を計算するロジックが依存している要素が格納された配列
依存関係
A→R
S→R
⇆RはAとSに依存している
Reduxとは
Reduxとは、React.jsで使用するstateつまりアプリケーションの状態を管理するフレームワーク
Reduxの要素
State:アプリケーションの状態
Action:ユーザーが何押したいかという情報を持つオブジェクト
Reducer:Actionを元にStateを更新するメソッド
Store:Stateの情報を保持している場所
フローチャート
①ActionCreatorsによってactionを作成
②actionをdispatchする
③Reduccerによってstore内のstateを更新
④ReactとReduxの連携し、store内のstateをconponentで参照
Reduxを使うメリット
Reduxを利用すればどのコンポーネントからも同じ方法でデータの共有ができる
Providerコンポーネント
ReactのコンポーネントからReduxのstoreにアクセスするために必要となります。
Reduxで共有化したデータにアクセスするためにconnect関数またはuseSelector Hookを利用
containerコンポーネント
Container コンポーネント :「Redux の Store から値を注入するためのもの(あとdispatch 関数)」
Refについて
Ref は render メソッドで作成された DOM ノードもしくは React の要素にアクセスする方法を提供します
いつRefつかうのか
フォーカス、テキストの選択およびメディアの再生の管理
アニメーションの発火
サードパーティ(第三者)の DOM ライブラリ(HTMLのツリー構図的な、)との統合
実際につかうところまで
①Refを作成する
②Refにアクセス
ref の値はノードの種類によって異なります。(ノード:ツリー構造の点見たいな感じ)
・HTML 要素に対して ref 属性が使用されている場合、React.createRef() を使ってコンストラクタ内で作成された ref は、その current プロパティとして根底にある DOM 要素を受け取ります
・ref 属性がカスタムクラスコンポーネント(自作のコンポーネント)で使用されるとき、ref オブジェクトはコンポーネントのマウントされたインスタンスを current として受け取ります
(インスタンス:クラスは一種の雛形であり、同じクラスから作られたインスタンスは同じ変数(プロパティ)と手続き(メソッド)を持つが、各プロパティに代入されるデータ(値)はそれぞれのインスタンスごとに固有となる)
・関数コンポーネント (function components) には ref 属性を使用してはいけません。なぜなら、関数コンポーネントはインスタンスを持たないからです
(関数コンポーネントに対して ref が使用できるようにしたい場合は、forwardRef を(必要に応じて useImperativeHandle と組み合わせて)利用するか、コンポーネントをクラスに書き換えます)
③DOM の Ref を親コンポーネントに公開する
refのフォワーディング
Ref のフォワーディングを使うと、コンポーネントは任意の子コンポーネントの ref を自分自身の ref として公開できるようになります
ref のフォワーディングはオプトインの機能であり、それにより、コンポーネントが ref を受け取って、それをさらに下層の子に渡せる
useImperativeHandle
useImperativeHandle:親コンポーネントに渡されるインスタンス値をカスタマイズするHooksの一つ(関数コンポーネントにメソッドを追加し、それを親コンポーネントから使えるようにするための機能)
useImperativeHandleは第三引数に依存配列を渡すことが出来る
正しく使うことで、同じ内容のメソッドを何度も作り直してしまうことを防げる
storybookについて
storybookとは?
UI開発のツール
一度に一つのコンポーネントを操作できる
Storybook を使用すると、コンポーネントを再使用するドキュメント化(わかりやすくまとめる)し、コンポーネントを自動的に視覚的にテストしてバグを防ぐことができます。応答性の高いレイアウトを微調整したりアクセシビリティを確認したりするのに役立つアドオンのエコシステムを使用してストーリーブックを拡張します。