tekitoumemo’s diary

C#、.NET系の技術ブログを書いています。みんなの洋楽ランキングを運営しています。

【第2弾】React使ってちょっとしたもの作った

大したものじゃないんですが、課題だった日付の検索プルダウンを実装しました。数年に遡って週ごとにプルダウンを出してたのですが、使いづらすぎる、量が多すぎる、パフォーマンスも気になるので整えました。インデックスが1000を超えたので(ページ数は2000弱)、そろそろサイト内でいろいろ見れるように整理する段階に入ったかなと思って使いやすくすることが課題でした。

前置きが長くなりましたが、どういう風に変えたのか画像を貼ります。

変更前↓

f:id:tekitoumemo:20180908191148p:plain
手抜き杉。

変更後↓

f:id:tekitoumemo:20180908191348p:plain
デザインも整えて検索しやすいようにしました。まぁ、この検索方法はどっかの有名サイトの丸パクリなんで間違い無いでしょう笑

2時間ぐらいでできるかなーと思ってましたが、結局、8時間(一人日)ぐらいかかっちゃったので苦戦したところをさらっと書きます(ちなみにReactはドドド初心者、Angularは3ヶ月程度仕事でやってる)

this.setState is not a function

なんやこれ?と思って調べたらbindを使わなきゃいけないらしい。書き方は以下。

this.{メソッド} = this.{メソッド}.bind(this);

なんかthisの指すところが違うからbindしてthisを示す必要があるみたい(よくわからないけど)

TypeSctiptが辛い

修行だと思ってるけど本当に苦行。めんどくさいのでstate、propに型をanyにしてるのですが、いちいちcastしなきゃいけなくてめんどい。型宣言するとスラスラ書けないからanyにしたけど結局めんどいから、結果どっちもめんどい(笑)これとかねもう。

this.state.tests as string[]).map((value) =>
    <option value={value} selected=true >{value}</option>
)}

つらみ

他Domが操作できなくて辛い

Aungularでもできないのですがね、Reactだと出来ると思っちゃった(笑)Jqueryの置き換えだから結構めんどくさかった。
なんとか出来るのですが、非推奨なのでやらないでください。結局onchangeで対応した。

refでやる

<input type="email" ref={ input => { this.Input = input }} />
React.findDOMNode(this.refs.Input)
結局fetchでいいよね?

使いやすいからfetchを選定してるけど、どれが良いのかわからん。

コンポーネント化することでサーバー側のコードが綺麗になる

コンポーネント化することで、クライアント+APIで対応出来るのでその分サーバ側のコードが減りました。
辛いところじゃないと思うのですが、直すところが増えるので大変。ここも時間かかった一つの要因だけど、結果よかった。

いろいろ辛かったけど、結果綺麗に出来た気がする。

次はこれやるよー多分
github.com

AutoMapperでifって書きたいときどうするか

http://taswar.zeytinsoft.com/wp-content/uploads/2011/03/automapper-logo.jpg


automapper.org

C#のWEB開発ではAutoMapperが欠かせないレベルでかなり重要なのですが、完全にマッピングするのはやっぱり難しかったりします。MapFromだと三項演算子しか書けなくて読みづらい場合も出てくるのでifでかける方法を探しましたらあったので、備忘録的に書き残しときます。

まず普通のMapFromで書く場合(下のリンク丸々引用)

Mapper.CreateMap<SomeViewModels, SomeDTO>()
    .ForMember(dest => dest.Date,
            opt => opt.MapFrom(src => src.HasDate == "N" ? null : DateTime.Parse(src.Date.ToString())));

この程度ならいいのですが、もうちょい複雑になると困ります。なのでifで書くときはResolveUsingを使います。

ResolveUsingの使い方

Mapper.CreateMap<SomeViewModels, SomeDTO>()               
         .ForMember(dest => dest.Date, o => o.ResolveUsing(Converter));

private static object Converter(SomeViewModels value)
{
    DateTime? finalDate = null;
    if (value.Date.HasDate == "N")
    {
        // so it should be null
    }
    else
    {                                   
        finalDate = DateTime.Parse(value.Date.ToString());
    }                               
    return finalDate;
}

Funcを渡せるので非常にわかりやすくなりました。MapFromとResolveUsingだと若干違います。

void MapFrom<TSourceMember>(Expression<Func<TSource, TSourceMember>> sourceMember);
void ResolveUsing<TResult>(Func<TSource, TResult> resolver);

ResolveUsingはExpressionがないですね。これだと完全マッピングの道に近づくからうれしい!(まぁ、AutoMapperで完全マッピングすると逆にカオスになりそうですが笑)

Azure Schedulerの簡単な説明と使い道について

azure.microsoft.com

結構前からあったサービスですが、「これ結構使えるじゃん!」って思ったので簡単な使い方と僕なりの使い道を説明できれば。

Azure Schedulerとは

Azure Scheduler では、Azure の内部と外部でサービスを呼び出すジョブ (HTTP/S エンドポイントの呼び出しや、Azure Storage キュー、Azure Service Bus キュー、トピックへのメッセージの送信など) をクラウドに作成します。ジョブを今すぐ実行するか、定期的なスケジュールで実行するか、または今後の特定の時点で実行するかを選択できます。

定期的に動かしたい処理を実行できるサービスってことです。クエリやらストレージ処理やらRESTやらいろいろ対応してるよってやつ。ここら辺の用途でAzure FunctionとかWebJobが有名ですが、一番簡単でかつシンプルに管理できるので使い勝手がめっちゃ良いと思ってます。

値段は?

f:id:tekitoumemo:20180903003142p:plain
azure.microsoft.com
ここを見てもらえればわかるのですが、1分単位で最大50ジョブまで使えて1500円強です。まぁこんなもんですかね。タスクスケジューラーとかで管理しているコストを考えれば安いし、でも高いしみたいな。昔はFreeで1時間単位のやつがあったようですが、なくなっちゃったんですかね?それとも従量課金だからかな?まぁいいや

簡単な使い方

Azureのポータルからすべてのサービス>管理ツール>スケジューラ ジョブ コレクションを選択します。
f:id:tekitoumemo:20180903004006p:plain
以下の画面からタスクの設定を行います。

  • 名前

スケジューラーの名前を入力します。用途に合わせて設定してください。

  • ジョブコレクション

プランの設定です。3種類あるのでこれも用途に合わせて設定してください。僕は1500円の一番安いやつを選びました。

ここも用途に合わせて。

  • アクションの設定

ここは、REST APIを投げるパラメータの設定やらなんやらです。

  • スケジュール

スケジュールの設定です。1分単位で設定できます。UTC+9が日本時間なので、用途に合わせて設定して下さい。
f:id:tekitoumemo:20180903004224p:plain

どんな感じ?

f:id:tekitoumemo:20180903005218p:plain
僕の場合は4つジョブを設定しています(もったいな!)。ちゃんと実行結果が出て、エラーが発生したら何回リトライするか、どんなエラーか詳細にわかるので良いですね。レスポンスがなかなか来ないAPIだとタイムアウトになっちゃうので、そこらへんはいつか調べます(絶対調べない)。

どこに使えるか

スケジューラーなので定期バッチなどに使えるかなと思います。僕のサイトは、規模が小さく、夜中のアクセスがほとんどないので一つのサイトにAPIをまとめていて、4〜5時の間で実行しています。今までの定期バッチだとタスクスケジューラーで定期的にconsole Appを実行するって流れが一般的だったと思うのですが、RESTにすることで意味不明な名前だったり、意味不明なオプションがはっきりして管理しやすいなと個人的に思います。RESTの良いところは、基本名詞で名付けて動詞はHttpメソッドでわかるので、ドキュメントにも起こしやすく管理しやすいのがメリットだと思います。RESTについては、以下のサイトがわかりやすかったかなと。
qiita.com

Azure Functionを試したのですが、書き方が若干異なったり、サービスとソースが分かれる(ここはあまり調べてないからわからない)のがしっくり来なかったのでこれが一番シンプルで管理しやすいかなと思いました。

定期処理をどうするかは課題で、お金をかけたくなかったのでGCPなど調べましたが管理する場所を分散させるのは一番のコストだなと思いました(学習面も含めて)。若干お金がかかるのがマイクロソフトのやらしいとこだなぁと思いますが、だいたい欲しいと思ったPaasが一番揃ってるのはAzureの良いところだなと実感しました、

結婚式の準備が終わってるレベルで大変だった

全く技術関係ない笑

とりあえず、スゲー大変だった。まぁ、参考になるか分からんけどつらつら書いていく。ちなみに男目線の話。結論としてはちゃんと計画的に準備しないと辛いからコツコツやった方がいいよってことを書いてく感じ。

式場を探すときもちゃんと考える

ブライダルフェアで、高級料理食えるよとか言われるけどちゃんと選んだ方が良いです。フォアグラなんて毎週食べるもんじゃないすね。毎回見積もりを出されるのですが+100万で考えた方が良いかも。結果的にどこも同じような金額になるので、20〜30万ぐらいの差額で式場決めるのはもったいないとおもいます。

ブライダルフェアの愚痴は以下に書いてました(笑)

呼ぶ人を真剣に考える

ここはガチ。適当な友達は絶対呼ばない方がいい。あまり仲良くないのに飲み会とかで「参加するから呼んでー」とか言う奴はフルシカト。ここは、ご祝儀に関わるところだから後味悪いと嫌だしね。まぁ、ここは人それぞれかなぁ。

招待状を早めに手配する

プランナーから指示があると思いますが、招待状を早めに手配した方が良いです。書く時間があるから結構だるいっす。

ドレスは何回も試着してから決めよう

これは妥協試着ダメ。一番いいと思ったものを着ましょう。一生残るので、着たいものを着させたあげましょう。男は一番安い適当なもんでおっけ。

動画は構成から決めてつくる

曲とどんな画像を差し込みたいか決めます(赤ちゃんの頃の写真とか入学とか)。曲は良いところで終わりたいので、ネットで拾ったような画像やらでプロトタイプを作ります。最後に写真を差し替えるだけで、ちゃんとしたムービーになりますよ。この方法でプロフィールムービーを諦めていましたが、一日で撮影と編集が完了しました。ちなみに動画編集ソフトはiMovieです。

DVD書き込みはIDVDっす。これはhigh Sierraでも無理矢理インストールできるのでこちらを参考に

iMovieのテキストがクソダサいのでアニメーション作成のアプリを使いました。

複数の動画を並べられるやつ

これ無敵。

昔の画像はスキャナー使う

スキャナーあるとマジで楽っす。僕はこんな感じの持ってたんで役に立ちました。

席次表は業者にお任せ

このサイトで作りました。正直、値段とか安くないし、全然席次表に向いてるものじゃないから無理にオススメはしないかな。席次表の画像とか、テンプレートがいいのなかったから自力で作ったりとかそんなに席次表には向いてないです笑。まぁ、品質は結構いいんじゃない?って感じ。


チャットする

基本、担当分けして作業していました(嫁は動画、俺は画像加工やらなんやら)。同じ場で作業してるんですが、urlとか共有したかったりするんでチャットを使いました。俺はGoogle Photoの関係でハングアウトを使いたかったのですが、なぜか嫁がSlackゴリ押しだったんでSlackにしました。

Googleアカウントで入ってるのにSlack意味ないっす

CDはメルカリ、TSUTAYA

僕は時間がなかったのでブックオフTSUTAYAで買ったんですが、余裕を持ってメルカリやTSUTAYAで買った方がいいです。TSUTAYAはレンタル落ちの新作が売ってるので、安いし種類が豊富。ブックオフは高いし、新しいのがない。一回しか使わんのならレンタル落ちでいいよね。Spotifyでプレイリスト作ったんですが、なかなかテンション上がるのでいいですよ。

ウェルカムボード、席札はハンズで

ここら辺も手作りだったんで、ハンズに行きました。注意なんですが、ウェディンググッズは大型店舗しかないので、調べて行きましょう。全部で1万ちょいかかったかな?

ご祝儀多かった人には御礼を

やらしい話だけど、ここで友達度がわかる気がします。さすがに3万以下は一人もいなかったけど、昔からの付き合いあるやつなんかめっちゃ多くてビビりました。いくら親友とはいえども、はみ出た分は必ずお礼を。目安は祝儀の3/1。高すぎると相手も困るので、善意としてくれてる前提を考えたら3/1が妥当です。あと引き出物でギフトは渡してるので、なんか違うやつを選んだ方がいいかと。僕は一休のギフト券を渡しました。

職場の人は、引き出物で高いので渡してるから控えめにしました。

ホテルをとる

都内で式を挙げたので、ちょっと家から遠くていろいろ困るのでホテルを取りました。式終わって荷物詰めてあとは飲みに行くだけ。終電気にせず飲めるので楽っす。

二次会三次会四次回は絶対行きましょう

僕は二次会やらなかったんですが、意外にみんな待ってくれてました。式が昼過ぎに終わって、そのあと呑みまくってホテルついたのが2時過ぎ。これは感謝しかないですね。出来るだけみんなに会いましょう。


書き起こすと結構大変やなと実感してみたり。まだまだやったことはあるんだけど、これから結婚式をする人の参考になればと思います。

.Net CoreのRazorエンコードとかSEOの影響とか

.Net CoreのRazorは、デフォルトでエンコードされるように出来てます。これが普通に最低でした。みんなの洋楽ランキングは、タイトルをシステムで出力したりしてるんですが(以下)、それが全部エンコードされてわけわからん感じになります。

<title>@ViewBag.Title - みんなの洋楽ランキング</title>

こんな感じになる
f:id:tekitoumemo:20180806213305p:plain

.NET CoreのRazorはデフォルトでHtmlEncoder.Defaultってのが使われているのですが、これをエンコードしないようにDIして制御しなければいけません。なので以下のコードで制御します。

services.AddSingleton (HtmlEncoder.Create (UnicodeRanges.BasicLatin,
    UnicodeRanges.CjkSymbolsandPunctuation,
    UnicodeRanges.Hiragana,
    UnicodeRanges.Katakana,
    UnicodeRanges.CjkUnifiedIdeographs));

これはシングルトンにしてください。

f:id:tekitoumemo:20180806213842p:plain
最近SEO下がりまくってアクセスが激減したのですが、いくつか要因があるので一つずつ潰してます。
iTunesアフリエイトSVGがクソ重い(改善済)
・HTMLエンコード(改善済)
・導線とコンテンツ不足(日々改善)
一旦これで様子見て経過を書いていきます。まぁ今月は1万PV割れする可能性大なのでボロボロですね。

Net Frameworkではこんなことなかったので、気をつけなければ。。

.Net Coreの部分ビュー

同じビューを何回も書き続けるのが微妙なので、ASP.NET Coreでは部分ビューってのがあります(どのフレームワークにもあるけど)。ASP.NET5でもHTMLヘルパーであったのですが、ちょっと書き方が変わってるので備忘録として。

HTML5であった@Html.Partialとほとんど同じ機能ですが、.NETCoreになってHTMLヘルパーからタグヘルパーに変更されたのでクソダサい記述はなくなりました。さらにasync、awaitが使えるので非同期でビューを動かすことができるので、重いビューでも多少は大丈夫になった感じですかね?わざわざJS使う必要がないところとか良い感じでしょうか。

部分ビューとは

部分ビューとは、別のビュー内でレンダリングされるビューのことです。

1枚のページに複数のHTMLがかけるよ!しかもMVCでってこと。つまりこういうことです。
f:id:tekitoumemo:20180805220945p:plain
この赤い部分は再利用するので部分ビューにしています。

部分タグ ヘルパー

以下の記述ではViewsのSharedにある_TestPartial.cshtmlがタグを記述したところに挿入されます。

<partial name="_TestPartial" />

非同期もいけます。

@{
    await Html.RenderPartialAsync("_TestPartial");
}

パスを指定すれば、ディレクトリわけもできます。

<partial name="~/Views/Hoge/_Test.cshtml" />

モデルをバインドされる場合は以下です(試してない。

<partial name="_Test.cshtml" for="Model" />

非同期は、.NETCoreになってから追加された機能(おそらく)なので、わざわざJSフレームワークでやる必要はねぇなと思う場所には使えるかもしれません。モデルバインドも部分ビューもめっちゃ使えるのですが、結局依存しまくって汎用的に使えなかったり、技術負債になりがちなのでちゃんと考えて使った方が良いかもしれませんね。導入するのは比較的簡単なので、ビューのメンテナンスがめんどくさいなと思ったら導入するぐらいの気持ちでやった方が良いと思います。

React使ってちょっとしたもの作った

今週、seo下がっちゃってアクセス数激減してます、つらみ。今月は21KPV着地しそうです。今回はReact使って「いいね」機能を作ったので、簡単な仕組みと感想文を書きたいと思います。

f:id:tekitoumemo:20180726203349p:plain

上の画像の通り、いいねを作りました。会員登録とか無いサイトなので「いいね」作っても意味はないと思いますが、React使ってみたかったんです。以前に書いたSPAじゃないReactの延長みたいなもんです。

簡単な仕組み

みんなの洋楽ランキングには、会員がいないので誰でも「いいね」が出来ます。「いいね」して、また来たときに「いいね」の状態が残ってないと萎えるので、状態を保存するためにローカルストレージを使いました。

クッキーだと、最大20個?までと制限があるので、10M保存出来るローカルストレージが最適でした。ストレージにはJsonで状態を持ってる感じです。サーバ側はCRUDAPI作って押した状態(付けたか外したか)によって呼び出すAPIを変えています。

デザイン

Instagramモロパクリしてます。本当はTwitterを丸パクリしたかったのですが、cssの知識がないので妥協しました(下のリンクみたいにしたかった、かわいい)
https://isaito-kurumizawa.github.io/GoodButton/

出来なかったこと

今月と来月は時間を作ることが難しくなるので、仕事終わってから2日で仕上げました。やはり色々課題が残っちゃいました。

・Azure でnpm i出来てない。
しょうがないからgithubにnode_moduleをブッこむという荒技を使ってます。ちなみにAzure Web Serviceはデプロイ時にnpm iしてくれるのでAzureは悪くないです。単純にpackage.jsonの書き方が悪いだけだと思います。デプロイはnpm i productionなので下見て変えれば大丈夫だと思う。

・スタイルが効かない
Reactのスタイルはhtmlに書き込まれるのですが、なんかデプロイしたら効かなかった。まぁcssはminifyしてるんで、ここら辺はどうでもいいかなと思ってます。おそらくPhysicalFileProvider使わなければいけないのかな?

・Redux使えば良かった
単一コンポーネントなので無駄に分散させる必要ないなーと思ってたから使わなかったんですが、勉強がてら使えば良かった。

普段Angular使ってる私がReact使ってみた感想

今仕事でAngularを使っていてAngular歴3カ月程度になります。Angular嫌いでロクに勉強もしてないので仕組みとかよくわかってないですが、React使ってみてAngularの良さがわかったのでちょっとぼやき程度に話したいと思います。

Angularはちょー難しいけど、スキルが低いチームほど使った方が良い

一般的にはReact、Vue.jsの方が初心者向けと言われてるのですが、API群が少なく開発者が選定しなければいけません。これの何が難しいのかというと他人のソースをパクりにくいので、統一してコードを書くのが難しいだろうなぁと思います。Angularは、基本的にRxJs、InputOutput、typescript、ライフサイクルさえ覚えればだいたいみんな同じコードが書けるようになります。つまり、ほぼAngularで完結するようなAPI群が揃ってるのでスキルレベルに左右されないチームが出来るってことになります。現に今のチームでダントツで仕事ができない僕でも多少なんとかなってるのでまぁ良いフレームワークなんでしょう。ただ、難しいのはやっぱり状態管理で、ReactみたいにRedux使おうぜ!みたいな風潮がないので、普通に作り上げるとバグを潰す期間が必要で普通に辛いです(@ngrx/storeってのがあるんですけどね)また、DIのせいでテストを書くのがめっちゃむずかったりするんでそこらへんはスキルが必要なんでしょう。その点、Reactは初見でも理解が出来て、ステートレス推奨してるので僕はReactの方が好きですね(まだ2%ぐらいしか理解してないけど)。Angular難しいし、1系から2系に変わって全然違う言語になった嫌われ者なので僕も嫌いでしたが、だんだん理解が出来るようになりました。Angular6からRxJsの変更がえぐいのでまた嫌われそうですね(笑)


こんなのがあるんですね。便利。
github.com