React 案件での面談時の質問事項

#React 案件での面談時の質問事項
案件がそろそろ変わるので面談用に確認して置きたいことをまとめておきます


## Reactだけなのか React + reduxなのか?

当然ですがここはまず確認します
これによって設計が大きくことなるからです

Reactのみの場合「*そもそもSPAなのかどうなのか？*」という話にもなり、
サイトの一部分のみをReactで制御する案件もあるので
その場合、**Reactを扱えるのはその機能の本の一部分でhtmlとcssによる保守運用がメイン**になる可能性があるからです

個人的にですがReact単体で使用している案件の場合、学習コストを抑えるためReactのみで行うという理由が多かったりします
そういった案件はreact-routerや、ミドルウェア周りもなく
**gulp + gulp-webpack + react + jQuery** という環境だったりします

~~(なぜVueではなくReactを選択したのだろうか)~~


##CSSの設計
- **css modulesなどで設計されているのか？**

ReactのCSS設計は厄介です
各現場によって違い色々と文化が違います**css modules**なのか **css in js**　なのか
一番問題なのはただ**cssファイルをインポートしているだけ**のパターンです

```style.css

.hoge {
  color: red
}
```

```hoge.jsx

import from 'hoge.css';
const Hoge = () => (
  <div className="hoge">
    hogeee
  </div>
);
```
css modulesなどはグローバル空間の名前を汚さないように一意の名前になるように設計されているので
各コンポーネントで自由な名前をつけることが出来ます
しかし、上の内容だとグローバル空間の名前が汚染されていくのでBEMなどの命名規則で守っていくしかありません
もし、class名で悩まされたくないのであればこの質問で避けることが出来ます


##コンポーネント設計
画面仕様書だけ渡されて作る案件が結構多かったりします
コンポーネントの設計は画面実装者だけが把握するものではなくメンバー全体ですり合わせていく方がいいと個人的に思っています

似たようなコンポーネントなのに別の画面では違う実装の仕方をしていたり、
逆に使いまわされる前提で作っていたのに使って貰えなかった・・・ というのもあります

画面全体をプリントしてハサミなどで切ってコンポーネントを分けて、また構成してみるなどするとサイト全体を理解できてきます
この資料があれば新規参入したエンジニアの方がいても、この画面はこのコンポーネント郡で形成されていると説明も出来ると思います

Reactコンポーネントの設計でよくあるのが **Atomicデザイン**です
こちらの記事が詳しく書いてあったので参考になると思います
参考記事: [Atomic Design に学ぶ Web 開発をハッピーにするデザイン手法](https://qiita.com/usako/items/10ea7340f1a0b23a7b8b)

他には
・ **コンテナとプレゼンテーションで分けているのか？**
参考記事: [[redux] Presentational / Container componentの分離 - react-redux.connect()のつかいかた](https://qiita.com/tuttieee/items/a3ca7d9d415049d02d60)

・ **stateless functional components で作っていくのか？**
参考記事: [ReactのStateless Functional Componentsの書き方](https://qiita.com/ledsun/items/c577e004561b59f9a7e5)
参考記事: [Reactのコンポーネントをステートレスに！！！recomposeとは？ ~0からreact習得記 day 09~](https://qiita.com/ryo_t/items/b5bfbf70c97c85461689)


## リファクタのタイミング
- **PRを送る前？**
- **リードエンジニアが適宜行う？**
- **品質チェックなどのテストの前に行う？**
- **リリース後に行う？**

たとえばコンポーネントの実装が完了していて、そのあとこうすれば良かったなどはよくありますが
一個人が勝手な裁量でガシガシとリファクタする現場は後々炎上します
リードエンジニアの方がdevelopブランチなどでやってたりするとPRを送る頃にはコンフリクトしまくりでマージ出来ずに死ねます


リファクタリングをいれると以下の作業が発生すると思っています

- 該当箇所の修正
- 他画面への影響調査
- 影響があればそれの水平展開
- 修正内容のテスト
- PRの指摘対応
- リファクタリングを行った経緯とそれによる効果のメンバーへの周知

上の作業にどれだけの工数がかかるのか、また予想外の対応に備えられるのか
それに対しての検証及び再調整やPRのレビュー対応諸々の時間を考慮しているかは気になります





## デザインはFIXしているのか？
これはReactとは関係ないのですが重要な事なので
現場によっては貴方はデザインが出来ますか？と聞かれたりします
それは、デザインは常に検証されていて日々新しくなっているよ！ということかもしれません
UXやUIを任せられるなら画面のデザインは仕上げたから細かい調整はお願いね！と投げられるかもしれません
具体的に確認したい項目は

- **バリデーションエラーのメッセージ**
- **APIからデータ取得時の状態(ローディングなど)**
- **データが存在しない場合**
- **エラーレスポンスが返ってきた場合の表示**
- **0件時の表示**

画面を作るのは構わないのですが、これが最初のスケジュールの**工数に含まれていない**ケースもあります
リニューアルや新規立ち上げのサービスの場合は要注意です

運用保守の場合はあとはデザイナーの方とすり合わせていくだけなので問題なさそう



## 状態の管理
reduxは原則`setState`は使わず、actionからdispatchのフローでstoreを更新して状態を変えていくのが基本だと思います
ただアコーディオンやモーダルの開閉など、各コンポーネントで完結する場合はどうするのか？

そのクラス内でしか使わない状態をストアに突っ込んでdispatchしていくのもなぁと思います
例えば、アコーディオンを開閉する機能をsetStateで作るとこうです

```accordion.jsx

accordionToggle(){
  this.setState({
    isOpen: !this.state.isOpen
  });
}
```

開閉の処理はたったこれだけなのに、そのためにaction、reducerなどのファイルをつくるのはちょっと抵抗があるのですが
どうなんですかね？

というのを大体現場で聞いたりしています
プレゼンテーションとコンテナーのコンポーネントで分けて、ストアで状態を管理した方がテストしやすいからって認識であってますかね？

## ミドルウェア
これも現場によりけりですが、cssと違ってどんなのを使っているのか気になるだけですね
redux-sagaなのかredux-chunkなのか知らないものであれば慣れるだけですし、知ってれば楽だなぁぐらい
無ければこりゃ頑張るしかないなｗって感じ

~~Reactはよくも悪くも**気合でなんとかなる**イメージ~~

なければ**promise**や**async**でやるんだろうって感じ

## テスト系
ここは自分が今までうまく導入できなかったので聞きたいのだが適切な質問が出来ない・・・
今度の案件で色々触れるらしいから勉強します

## 型
テスト系と同じく、こちらもflowやTypeScriptをまだうまく導入できなかったのでまとめられない・・・
誰か適切な質問を教えてほしいです・・・


##バリデーション周り
inputフィールドなどのバリデーションチェックについてです
inputの属性にもバリデーション用の属性がhtml5であります
そちらはブラウザによっては動作しないので、おそらく自前で実装すると思うのですがどんな実装なのか気になる

例えば、Inputコンポーネントなどを作ってそれを継承してバリデーション用のコンポーネントを作るのか
それともバリデーション用の機能を用意して[**HOC**](https://postd.cc/react-higher-order-components-in-depth/)などでラップするのか
作り方は様々あるのできになりますね〜〜

inputフィールドの下にエラーを出すぐらいなら簡単に出来るのですが、
**submitのタイミングでエラーのあった箇所の一覧を画面下部に出す**とかだとちょっと面倒なんですよね笑

自分が作るならinput要素の **validity** にはバリデーションのフラグ情報が入っています
それを```ref```で参照するなどすれば、stateで変更せずに済むなぁとか考えています(※最新のブラウザ環境の場合)

参考記事: [htmlだけでinputの合計した入力値を出力 Output - バリデーションメッセージの表示](https://qiita.com/choro/items/78a706ce59d0130c3ea9#output-%E3%82%A8%E3%83%A9%E3%83%BC%E6%99%82%E3%81%AE%E8%A1%A8%E7%A4%BA)
参考記事: [React refで作るチェックリスト](https://qiita.com/choro/items/843a2dd8bfe51c077d2e)

##404などステータスコードのエラー周り

どういう設計をしているのか気になりますが、
**[flux-standard-action](https://github.com/redux-utilities/flux-standard-action)**で設計されているのであれば悩む必要は特になさそう
参考記事: [Redux: Actionのコーディング規約 と redux-actions](https://qiita.com/yasuhiro-okada-aktsk/items/a14f7f37262fb6cf0bf8)

ミドルウェアも関わってくるのですが自分の場合だとredux-sagaで処理していました
```payload.error```が**true**の際にエラー用の関数にステータスコードとエラーメッセージを渡して処理していました


## コーディング規約
別にあればそれに則って書くだけなんですが、
ドキュメントベースなのか、eslintベースなのかで変わってきます
恐らくどこもeslintでチェックされていると思いますがwikiなどに規約が記載されているだけの状況もあります

・ **eslintが全てであればprettier入れれば済む話**
・ **visual studio code なら手軽にできる**
参考記事: [俺的備忘録 visual studio code で行う環境づくり](https://qiita.com/choro/items/825de16dfe2faf0d8905)

## 画像ファイル
※ 3/22追記です

webpackを使用していれば`url-loader`でファイルを扱うと思います
自分は**constant**ディレクトリを作ってそこにrequireで読み込んだ画像の定数を置いていました

```javascript

// 定数化して読み込ませる
export const CLOSE_ICON = require('images/icon/close.png');

//またはオブジェクトで定義する
const IMAGE = {
    ICON: {
        CLOSE: require('images/icon/close.png'),
        OPEN: require('images/icon/open.png'),
    },
    HOME: require('images/home.png'),
    LOADING: require('images/loading.gif'),
};
export default IMAGE;

```
~~思い出しながら書いているので間違っていたらすみません~~


gulpを扱っている現場では**スプライト画像**にして`background-image`で読み込むことも少なくないです
その場合の質問は
・**サーバーはhttp2に対応していますか？**
もし、既に対応済みであればスプライト画像にするメリットは特にないのでimgタグなどで普通に使うことを勧めてみます

参考記事: [HTTP/2 時代におけるパフォーマンスの最適化](https://capitalp.jp/2016/12/29/http2/)