開発の日々スマートフォン用の表示で見るよちよち開発の日々この広告は、90日以上更新していないブログに表示しています。2018-12-17reactのhooksを利用した状態管理ライブラリeasy-peasyを使ってみた最近reactのhooksが話題になっていますね。そのhooksを利用した状態管理ライブラリを見つけました。今回はこのライブラリを使用して簡単なgithubのリポジトリ検索機能を作成しようと思います。完成したコードは以下になります。hayawata3626/easy-peasy-sample以下からは、コード全てを説明するのではなく、主要な部分を中心に説明していきます。今回はcreate-react-appを使用しています。v16.7.0-alphaから使えるのでアップデートします。react-dom@16.7.0-alpha.0以下は今回使用するライブラリなのでインストールしてください。easy-peasyaxiosemotionmaterial-uilodashこれで環境構築は終了です。このライブラリで使われるのが主にeffect、actionです。effectは副作用のあるもの、非同期にデータを取得する時などに使用します。フォルダ構成フォルダ構成は以下のようになっています。model.jsstoreの作成githubのREADME.mdにも説明されていますが、以下のようにstoreを作成します。公式から引用したコードです。}};createStoreをimportします。createStore(model);これでreduxのstoreと同じようなものを作成できました。以下は実際にstoreを作成したコードです。document.getElementById("root"));serviceWorker.unregister();reduxとに似ていますね。必要なデータは以下になります。false,}itemsにはapiから取得したデータが一つ一つ入ってきます。loadingは検索中の時に表示したいので初期値はfalseです。今回メインとなるactionは以下になります。},}キーにはaction名、値には関数を書きます。actionは第一引数にstate、第二引数にpayloadを受け取ります。payloadにはactionが発火した時のデータが入ります。actionを作成していきます。今回のようにgithubからデータを取得するときなど、非同期で何かをしたい時に使用します。以下のコードをみてください。(公式ドキュメントから引用しています。action内では直接stateを変更していません。代わりにdispatchを受け取り、actionにdispatchすることでstateを変更しています。下記のコードを追加しました。})};payloadには検索フォームで入力した文字列が入ってきます。あとはプログレスを表示・非表示するだけです。これで主要なロジックの部分が終わりです。コンポーネントの作成コンポーネントを作成していきます。);}大事な箇所は以下の部分です。dispatch.fetched);useActionはコンポーネント側でstoreのactionがほしい時に使います。上記ではactionを一つしか呼んでいませんが、もう少し複雑なアプリケーションになると複数のactionを一つのコンポーネントで使いたいケースが多いと思います。そのような場合は以下のように使用します。);}ここでキーとなるのがuseStoreです。コンポーネント側でstoreに格納されているstateにアクセスしたい時に使用します。引数にはstateを引数に持つ関数を渡します。actionの時と同じように複数のstateを利用したい場合は以下のようにします。);};useStoreとuseActionはワード的にもわかりやすいですし、複数のactionやstateを取得したい時にも便利ですね。今回のコードには使用されていませんが、もう一つ紹介します。reduxのreselectのような機能です。}}stateを引数にもつ関数を引数にもちます。便利なapiが提供されていますね。react-nativeとも連携することができます。https://github.com/ctrlplusb/easy-peasy#usage-with-react-nativetsの対応は以下のissueにのっています。https://github.com/ctrlplusb/easy-peasy/issues/21以上でhooksで作成されたライブラリeasy-peasyの紹介を終わります。本当に簡単に実装することができました。今回は分割代入でオブジェクトにある特定のキーの値を取得してくる方法を見ていきたいと思います。経緯reduxのコードを見ている時に分割代入をしているコードを見かけて挙動が気になった。まとめ分割代入は便利ではありますが、読みやすさという点では最初理解しずらいところはあるかもしれません。それを踏まえても便利な点が多いので積極的に使っていこうと思います。ライフサイクル今回はReactのライフサイクルやPureComponent辺りについて紹介したいと思います。Handlingがあります。Handlingについては紹介しません。)Mountingreactjs.org以下のメソッドは、コンポーネントのインスタンスを作成してDOMに追加される時に呼び出されます。呼び出される順番は以下の順番です。getDerivedStateFromProps()render()componentDidMount()Updatingreactjs.org以下のメソッドはコンポーネントが再レンダリングされる時に呼ばれます。getDerivedStateFromProps()shouldComponentUpdate()render()getSnapshotBeforeUpdate()componentDidUpdate()ここで重要なのはshouldComponentUpdateです。コンポーネントがrenderされる前に呼ばれます。nextStateを受け取り現在のpropsとstateを比較します。更新するときはtrueを更新が必要ない場合はfalseを返します。注意したいのは、React.Componentの場合はshouldComponentUpdateはデフォルトでtrueを返すということです。React.Componentの場合はshouldComponentUpdateでロジックを書く必要があります。*/例えば親のコンポーネントの状態だけが変更し、子のコンポーネントのpropsやstateに変化がない場合に子のコンポーネントも一緒にマウントされます。するとコンポーネントの描画速度が遅くなります。React.Componentで書く場合は、ちゃんとshouldComponentUpdateを使って描画パフォーマンスを最適化してあげる必要があります。React.PureComponent次に最初の方で挙げたReact.PureComponentについてです。reactjs.org結論を先に言うとReact.PureComponentはshouldComponentUpdateの処理が実装済みとなっています。React.PureComponentを使うのが良いでしょう。compareするので以下のケースの場合、常にマウントされる結果となります。}}propsにはつねに新しいオブジェクトを受け取っています。compareなのでプロパティと値が正しくてもshouldComponentUpdateの戻り値はtrueを返してしまいます。今はオブジェクトの階層は深くありませんが、もっと階層がある場合などこのような場合などを考慮するとPureComponentの受け取るpropsやstateなどはシンプルなものにすると良いでしょう。深い階層でpropsやstateの値が変更されるとわかっている場合は、forceUpdate()を使うのも一つの方法です。Compareを使用していました。このアドオンがPure.Componentの役割を果たしていました。以下のように使います。npmshallowCompareメソッドには同じようにnextPropsとnextStateを渡してあげます。することでshallowCompareが比較してくれます。}}まとめReactのコンポーネントの描画する仕組みを知っておくことで、最適な描画パフォーマンスを実現できると思います。今回紹介したもの以外にReact.memoやrecomposeのpureなどがあるので次はこれらについて紹介したいと思います。03:01ReactのライフサイクルやPureComponentについてTweet広告を非表示にするもっと読むコメントを書く2018-11-03JavaScriptの非同期処理とスコープの関係性について今回非同期処理とスコープの関係性について紹介したいと思います。唐突ですが以下のコードをご覧になってください。}}countdown();出力結果はどうなると思いますか?結果は以下になります。このコードのポイントとしては、変数iがfor文の外にあるということです。setTimeoutが実行される時にはiの値が-1になっているのでsetTimeoutが参照する値が2行目のiつまり-1になります。}}countdown();結果は以下となります。こちらは意図としたように動きます。先ほどのコードとの違いは、変数iをforループの制御文の箇所で利用しています。JavaScriptの処理系はループの各ステップで新しい独立した変数iのコピーを作成します。setTimeoutに渡された関数が実行されるときに、自分の独自のスコープになる変数から値を受け取ることになります。言葉ではなかなかわかりづらいので下記のコードをみてみてください。500);}setTimeout関数が実行される時には上記のように各ステップで新しくコピーされた変数iを参照していることになります。まとめどうしてこのような結果になるのか最初理解するのに時間が掛かりました。JavaScriptにおける非同期処理とスコープについてはちゃんと理解しておく必要があります。17:45JavaScriptの非同期処理とスコープの関係性についてTweet広告を非表示にするもっと読むコメントを書く2018-10-24TypeScriptの型の互換性について今回はTypeScriptの型の互換性について取り上げます。型の互換性・・・??簡単に言うと例えば、ある型の変数であるHogeに、別の型であるFugaが代入できれば、型の互換性があると言えます。逆に代入できなければ型の互換性がないとなります。この型の互換性がどのように決まるかは言語によって異なります。Subtyping)が採用されています。実際にコードを見て確認します。20上記のようにPersonクラスがTreeを実装していなくてもメンバーが同じなのでコンパイルエラーにはならないのです。Subtyping)というのです。C#やJavaの場合は、PersonクラスがTreeインターフェースを実装していないといけないので上記のコードではエラーになります。(自分はC#やJavaを触ったことがないので別の機会でお試しください。このようなものを名目上の型付けと呼びます。y;こちらは正常にコンパイルされます。変数yが変数xのプロパティ(ここでいうとname)をもっているので割り当てが可能になります。x;お察しかもしれませんが、yに対応するプロパティをxはnameしか持っていないのでコンパイルエラーになります。関数の場合はどのように型を評価しているのでしょうか?以下のような関数があります。hoge;結果としては、fugaにhogeを割り当て可能です。注意する点としては、引数の名前が異なっていても型のみが考慮されるのです。hogeの関数の引数名はaですが、fugaの関数の引数名はbとcです。上記の例でみたオブジェクトの例では、プロパティ名が異なっていると正しく割り当てされません。hogeのように引数が切り捨てられるのが許される理由としては、関数の引数が無視されることがJavaScriptでよくみられるからだそうです。truesomeメソッドのコールバック関数のパラメーターは以下の3つを受け取ります。各要素のインデックス要素を格納している配列このパラメーターを全て使う時もあるとはありますが、使わないケースも多いです。このことから引数の切り捨てられるのが許されるようです。まとめこのようにTypeScriptには構造的部分型が取り入れられています。オブジェクトや関数などによって型の評価の仕方が異なるのです。次回はジェネリクスのことについて取り上げたいと思います。23:03TypeScriptの型の互換性についてTweet広告を非表示にするもっと読むコメントを書く2018-10-18JavaScriptにおけるfor文のまとめ今回は言語において基本中の基本であるfor文について取り上げます。daysなど期間を表す意味として使われます。このようにfor文は決められた回数のなかで何か繰り返し処理を書きたい時に使います。これとは対照的なものとしてwhileなどが挙げられます。実行結果/*appleorangegrapebanana*/forEach配列の一つ一つのデータに対してコールバック関数を適用することができます。...処理内容})コールバック関数の引数は最大で3つ受け取れます。引数は、配列の値、第二引数はインデックス番号、第三引数はforEachの対象となっている配列になります。注意する点としては、コールバックの関数内でbreakやcontinueは記述することができないということです。値を何かしたいといった時に便利です。一つ一つの構文がどのような役割をもっているかを理解しておくことは大切です。今日は簡易的なものですが、作っていきます。こちらアップロードした後の画面です。必要なものはブラウザとエディタです。見た目を整えるまずは、簡単な見た目の部分から作ります。src="main.js"></script></body></html>アイコンを使いたかったのでFontawesomeを読み込んでいます。}})このコードではまず2行目でinputタグのchangeイベントを取得します。{}その後3行目のfilesでファイル情報を取得しています。target_el.files;ファイルの数が1つでもあればif文の中を通ります。オブジェクトを使用するとユーザのコンピュータ内にあるファイルを非同期的に読み込むことが出来ます。以下参考にしてみてください。指定されたBlobオブジェクトを読み込みます。文字列や巨大な画像、音声ファイル、動画ファイルなどを扱うことができます。FileReader.onloadはファイルの読み込みが成功した時に呼ばれるイベントです。プレビュー画像のimgタグのsrc属性にreader.resultという値が入ります。このresultというプロパティには、ファイルのデータを示すデータURLが入ります。簡単なものではありますが、これで完成です。プレビュー機能があるだけでUXの向上に繋がると思います。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。