redux-state-validationというライブラリを作ってnpmで公開していますのでその話を今回はします
なぜ作ったのか
reduxのvalidationの仕組みを持っているライブラリは検索を行うと
redux-form
redux-validator
この二種類が出てきます。
ただこれらのライブラリはformおよびactionにvalidatorが紐づいており、redux-formにおいては、formの入力方法をたくさん作成するほど、redux-validatorについては、actionをたくさん定義するほどvalidationを冗長に書かなければ行けなくなり、大きなアプリケーションを作る際に非常に効率が悪くなってくるのではないかと思いました。
webとnativeの共通構造化を考える上でredux-formをreact-native用のコンポーネントに突っ込むとなると微妙だなと思い、色々考察した結果、reducerのdispatchのstate変更時にvalidationをかけることができれば、十分なのではないかと思い作ることにしました。
具体的に何ができるかというと、reducerにvalidationを定義し、invalidation条件に引っかかるとrootのstateにerrors stateをくっつけます。errorsに関してはidを振り当てられるので表示したいところでidを使ったり、for文を回したり自由に表示してくださいというスタンスのライブラリです。reducerにvalidatorを定義するため、ほぼ記述場所を集約できます。具体的には、リポジトリを参考にしてください。
NG集
作ってく中でも想定外の問題が度々起きたので、あたふたしました。
## 失敗1 初期値の入力に失敗する
初期値はundefinedが入ってくるため、最初のバリデーションに引っかかった瞬間errorになっていました。
僕が設定したテストケースでは全てちゃんと初期値が定義されているものしか実証していなかったため、想定から漏れていました。気づいて即日修正しましたが、この時期にインストールした人には多大なるヘイトをためたことでしょう。今思ってもわざわざ楽でもないコードに独自の設定突っ込ませ挙句、よしやってみようと思って、いきなりエラーかましてくるなんて最悪のUXですね。この件でユーザーがちゃんとつく前にREADMEとかに開発途上の段階ではWARNINGでも書いとこうかと思いました。
## 失敗2 バリデーションがキツすぎて入力ができなくなった
reduxのstateとformの入力値が同期していると、電話番号のようにある程度入力長が決まっているものに対して、最初からlength固定値の制限をかけると入力値が空の状態で文字入力を行った時にバリデーションに引っかかり、全くstateに文字入力できなくなるというバグがあることに気づきました。これではまずいので、formのsubmit時に行われるバリデーションと毎回のバリデーションを分けることができるようにしました。具体的には、warningというoptionをつけたvalidatorに関してはstateの変更を許容し、つけないものに関しては、条件に引っかかった場合はstateを戻すという使い分けをできるようにしました。ただし、formからの入力かどうかを検知するためにはdispatchされたactionからなんらかのmetaデータや actionTypeによってバリデーション条件を追加しないと行けないので、 validatorにaction入力も許可しました。しかし、ここまできて、思ったこと。
\def\textlarge#1{%
{\rm\Large #1}
}
$\textlarge{ あ、これredux-formとredux-validatorの機能足し合わせただけry }$
# 結論
結論としては、このライブラリの利点はstate自体に紐づくvalidatorであるとため、ステイトの増減や変更に強いライブラリを作ろうとしたものですが、結局最低限、actionまたは、formに依存せざるを得ないことがわかりました。ただ、redux自体はreducerとactionは密結合なので、reducerの定義にactionを使ったバリデータを実装するのは問題ないかと思い、アーキテクチャ的にはいい感じになったかと思います。流行れ! react-nativeには、UIから入力制限をかける機能もあってそれで十分な可能性もあり、あくまで防波堤のような地味な機能なので、自分で作っといてなんですが、あんまり今の所恩恵を感じることができていません。しかしながら、防御壁とは常に身の回りにあって意識せずとも僕らを守ってくれているのだということだと思うことにしています。もし物好きな方がいらっしゃったら(2018/12/01現在は安定している...はずなので)ぜひ使ってみて、感想および、クレームをお待ちしております。極力善処します。
得られた学び
typescriptからnpmのパッケージ配信のノウハウやcommitizen,standard-version,type-doc,istanboolなどの使い方に詳しくなりました。code-coverageもストイックにやっています。ただ、coverage100% でも人間の想定範囲を超えるケースが発生することを体験したので、テストしてもこれなのだから、テストはしないとやばいよなっていう感慨を得ました。あとcommiter気分になってみるとこれメンテの辛さ結構感じましたね。OSSコミッターさんありがとう。