React17的基本概念总结(由业余爱好者整理)
首先
React对我来说是初学者。我只接触过教程,没有其他经验。我主要从事服务器端的工作。
因为考虑到React的设计,我感到有必要整理一下,但是网络上的信息零散且难以理解,所以我个人总结了一下。这是关于“即将开始的工作的整理备忘录”,并不是经过实践的结果。(也就是说,这只是空谈,可能会有错误)
如果有经验的人能提供意见,我将非常感激。
「べき」と書かれている箇所もありますが、それは「自分自身に向けた表現」であり、「誰にとってもやるべき」という意味ではありません。
当然ですが、PJの前提が異なる場合、適用する考え方も変わってくると思いますので。
必读之物
-
- 公式:https://ja.reactjs.org/docs/thinking-in-react.html
何はともあれ公式を見るべき
書籍:https://oukayuka.booth.pm/
プロジェクトメンバーでReactに初めて関わる人は全員読んでもらうべきだと思うくらい良書。
最新のテクニックが整理されている上、過去の経緯も含まれて丁寧に説明されているので、これを読めばWEBの情報で変な情報を掴まずにすみそう。
当然この記事に書いてないような情報が本当に盛り沢山!
全部で3部(+1部)あります。全部読もう!
https://oukayuka.booth.pm/items/2368045
https://oukayuka.booth.pm/items/2368019
https://oukayuka.booth.pm/items/2367992
https://oukayuka.booth.pm/items/1312815
文章前提
React:v17
希望的项目规模:相当大规模
以Native Chinese的方式重述以下内容,只需要一种选项:
React的基础知识
组件设计的基本知识
原理原则·思考方式(及其例子)
-
- 単一責任の原則・関心の分離
コンポーネント指向:1コンポーネントは単一の責任を持つ(複数の責任を持たない)。
コンポーネントは小さく保つ。
親の状態・子の状態に依存しないようにする。(やむを得ない場合はstateという手段がある。くらいのスタンスが良さそう。)
再利用性
可能な限りprops/stateは少ない方が基本的には再利用性は高い。
可変にすることで再利用性が高まる内容にとどめてprops/stateを用いる。
基本立场作为适用方法
-
- 最初のコンポーネント設計
大前提として、最初から完璧な設計を目指すのは避ける。実装の中で微調整が確実に生まれるため、最初はドラフト版くらいの感覚で作る。
設計の最初の立脚地点としてAtomicDesignの適用から考えていくのはわかりやすい。
ただし、そのまま適用は苦しむことが多いらしい。下記の「重要な考え方」に反してまで形に拘るのは避けるのが良さそう。
一番最初はみんなでワーワー話しながらベースラインを決めるのが良さそう。
Atomic Designから学ぶべき「重要な考え方」
コンポーネントの分け方
コンポーネント分割の基準が一定であり、わかりやすいこと。
プロジェクト内で共通認識が持てれば良い。AtomicDesignはあくまで一例、こだわる必要はない。
デザイナーと協業する案件の場合、デザイナーとデベロッパーで共通認識を持てる基準であること。
何かしらのメタファーを用いて、わかりやすい名前を見つけられるとテンションが上がる。
AtomicDesignだと科学だが、音楽(ハーモニー、メロディ、リズム)を採用しているプロジェクトもある。https://logmi.jp/tech/articles/300657
再利用を想定した分割/設計であること。
再利用しないものを過度に分割する必要はない。
可読性を維持するため、階層を深くしすぎない。
AtomicDesignは5階層。できればそれより少ない階層の方がわかりやすいはず。
ロジックをどの層に実装するかを事前に決めておく
PresentationComponent/ContainerComponentパターン:https://www.yuuniworks.com/blog/2018-05-18-presentational-component%E3%81%A8container-component/
まずは静的に表示できる範囲のものを作成する=PresentationComponent
動作については別で定義する=ContainerComponent
もし親子関係を定義するならPresentationComponentが親だと思う(けど、Presentationが子って記事も見かけた)
宣言的ということを考えるなら、Presentationが親の方が理解しやすい気がするけど・・・
コンポーネント設計の育て方
「Reactの流儀」をベースとして最初の実装および設計の調整を行う
モックから始めよう
Step 1: UI をコンポーネントの階層構造に落とし込む
Step 2: Reactで静的なバージョンを作成する
Step 3: UI 状態を表現する必要かつ十分な state を決定する
Step 4: state をどこに配置するべきなのかを明確にする
Step 5: 逆方向のデータフローを追加する
「3度目の法則」によるリファクタリングを行う
3度同じことを書くことになったタイミングでリファクタリングを行う。
再利用性を無駄に事前検討しなくて良いのが利点。
必要になった時に、再利用可能な形でリファクタリングする。
コンポーネント設計を見直すタイミングを作っておく
最初に考えたものはドラフト版。
どのタイミングが適切かはプロジェクトによるのでなんともいえない。
关于目录结构
-
- クックパッドのノウハウ:https://note.com/tabelog_frontend/n/n07b4077f5cf3
抽象度や依存の有無に応じてディレクトリをわける
特定画面のみで使うのか、複数画面をまたいで使うのか?
Entryポイントを独立させるのは保守性高そう。
ドメインが入るか入らないかを意識してディレクトリをわける
単なるUIパーツなのか、動作や意味合いが含まれるコンポーネントなのか?
bulletproofのノウハウ:https://github.com/alan2207/bulletproof-react/blob/master/docs/project-structure.md
読んでみてとしか言いようがない。世界的なノウハウが溜まってる物なので、これをベースに考えるのが良さそうな気がする。
在实施中的基本立场
-
- 宣言的な実装にこだわりたい(Reactの流儀Step3〜5):https://qiita.com/erukiti/items/fb7bcbd9d79696579d06
Reactに限った考え方ではなく、宣言的な実装はメインストリームになってきているため、考え方はシフトしていくべき。
宣言的とは、ソースコードの処理の流れを追わなくても、結果の状態が推測できるようになっていること。
基本的にはReact構文に従えば書き方自体は自動的にそうなるはず。
ただし、変数名から関連性がわからず、結果の状態が推測しにくくなることはありえる。
また、if文の乱用でもわかりづらくなりやすい。
レビュー観点としてこの観点を持っておいてもいいかもしれない。
例えば、分岐の多い表示処理は結果状態を想定しづらいので、コンポーネントを分割するか、Compound Componentを用いる。
あまり多用すると単一責任の原則から離れてしまいそうなので、上手く使うこと。
https://qiita.com/teradonburi/items/6828635d2e70dba6637d#compound-component%E3%81%A7%E5%88%86%E5%B2%90%E6%9D%A1%E4%BB%B6%E3%82%92%E9%9A%A0%E8%94%BD%E5%8C%96%E3%81%99%E3%82%8B
stateは必要十分なだけ使う。(Reactの流儀Step3)
まずは使わずに済む方法を考える。
次に、propsで代用できないかを考える。
「props drilling」など、シンプルなpropsでの実装では問題が生じる場合は、hooksのuseContext/useReducerの適用を考える。(これが実質的なstateの適用にあたる?)
stateが必要になる場合、適用範囲を最小限に絞る。
単一責任の原則および性能の観点:コンポーネント分割を前提に、stateで影響するコンポーネントを減らしてもいいかも。
単一責任の原則および性能の観点:useMemoを乱用は避けたいが、多少の利用なら許容する。
state管理が複雑になってきた場合はReduxの導入を検討する。
VoidFunctionComponentを使おう。(Reactの流儀Step5を実現しやすくする?)
propsがchildrenにアクセスできないようになっている。(より厳密なコンポーネント指向が実現しやすい)(v18でFunctionComponentから廃止予定のため、早めに対応できるようにするための存在)
型指定を強制できるため静的解析でエラー検知できるようになり、一定の開発に秩序をもたらしやすい。
Presentational Component / Container Component(Reactの流儀Step1〜2と3〜5を分けて考える)
「表示」と「動作」を分けて記載する方が望ましいという考え方。
「コンポーネント分割」での分離をまずは考える。(stateなどが絡みそうなら「React Hooks」の導入かな・・・?)
表示:「どのように見えるか」に関心を持つ。データや振る舞いを変更しない。(JSX(.jsx/.tsx)で構成すれば良さそう?)
動作:「どのように動作するか」に関心を持つ。データや振る舞いを変更する。(Typescript(.ts/.tsx)で構成すれば良さそう?)
古老的技巧:即使在谷歌上出现这些,也不要立即投入其中
-
- クラスコンポーネント → 今は「関数コンポーネント」が強く推奨されている。(徐々に推奨の強さが上がってるように感じる)
-
- ライフサイクル → v17から大きく変わっているため、古い情報かどうか確実に確認すること。
-
- mixin/HOC/render props/Recompose → 今は「React Hooks」が強く推奨されている。
-
- PresentationalComponent/ContainerComponent → 今は「React Hooks」が強く推奨されている。が、基本的な考え方(表示と動作の分離)はまだ活用可能。
-
- Redux → 「React Hooks」との使い分けないしは共存のさせ方が議論されている。hooksに触れてないReduxの情報は避けた方がいいかも。
-
- ContextAPI → 「React Hooks」との使い分けないしは共存のさせ方が議論されている。hooksに触れてないReduxの情報は避けた方がいいかも。
- 全般的に → 「React Hooks」登場以前と登場以降で結構考え方が変わってそうなので、hooks絡めるとどうなるんだろう?みたいな考え方は持っておいた方が良いかも。
似乎应该深入挖掘的事情
-
- v18機能 https://qiita.com/uhyo/items/bbc22022fe846fd2b763
平行レンダリング機能
サスペンスを使ったストリーミングサーバレンダリング
请留意以下事项。
- 全てを厳密に適用しようとすると、相反する要求が発生する場面がある想定。その場合は、PJの状況に応じて判断する。
测试的基础
- 全世界のノウハウ。といっても簡潔にまとまってるので、ひとまず見てみよう。
-
- React Testing Libraryは公式でサポートされるくらい有名なライブラリ。
-
- これを使わない手はない。
-
- (使い方はちょっと読み取りきれなかったけど、使うのは確定で良さそう。)
- 基本はレイアウトに関するテストのように見える。
主要是谈论从中间开始引入的情况。但是,单元测试的定位似乎可以作为参考。
-
- フロントエンドでTDDはほぼ不可能。(実装前に正しい振る舞いを定義することが困難というか、実装しながら設計/調整するようなのが基本。)
-
- 単体テストは、今後の修正が入った時に防衛的に機能するためのものとして作るスタンスが妥当。
-
- UXのテストは単体テストでは評価できない。ただ、UXに影響する変数は関数側に定義されているべき。
- 単体テストを途中から導入する場合、不要な依存が切れて、モジュールの境界面が自明になった状態にたどり着くことが最初のゴール。
使用 React Testing Library 进行测试的部分可以进行测试,但似乎有一些限制的预感。
-
- この記事以外に事例を見つけられなかった(検索能力の問題か・・・)のと、いいねが少ないのが気になる。
- 何かテストの実装で苦しむ場面あれば思い出して見返してもいいかもしれない。
额外赠品
例子
-
- 「このリポジトリの目標は、Reactアプリケーションを開発する際のリソースとグッドプラクティスのコレクションとして機能することです。」
-
- という海外のリポジトリの紹介をしてくれているページ。かなりわかりやすいので読むのが良さそう。
- その上で、その先のリポジトリも一読しておいた方が良い。
-
- SlackのようなチャットツールをSPA(シングルページアプリケーション)で作った場合の事例。(ヘイシャでした)
- (今回自分のPJとはちょっとアプリの性質が異なるが、ある程度参考になる部分はありそう)
- 「おてつたび」さんの事例。
-
- 「wantedly」さんの事例
- デザインのための仕組みづくりみたいなニュアンス。
关于原子设计 Shejí)的内容
-
- 公式:https://atomicdesign.bradfrost.com/
一番わかりやすかった日本語記事:https://uxdaystokyo.com/articles/glossary/atomic-design/
Atomic Design自体はデザインの考え方であって、実装の世界の話ではない。実装の世界に当て嵌めようとすると苦しみが多いという話が多かった。
でも、頑張って適用してるPJも、卒業してるPJも言ってることは一緒だった。
「開発者とデザイナーが同じ基準で会話するための土台の考え方を合わせる」
「メンテナンス性を高めるために、一定の基準・考え方でコンポーネントを分割し、適切なフォルダ構成を用意する。」:何が適切かはプロジェクトによって異なる→Reactの流儀を適用しながら見つけていくしかなさそう
いくつかの事例
sansanさんの例(Atomic Design導入タイプ):https://buildersbox.corp-sansan.com/entry/2022/01/06/110000
食べログさんの例(Atomic Design卒業タイプ):https://note.com/tabelog_frontend/n/n07b4077f5cf3
OHEYAGOさんの例(Atomic Design卒業タイプ):https://tech.ga-tech.co.jp/entry/react-give-up-atomic-design
Atomic Component:https://qiita.com/kahirokunn/items/b599d2cf04d2580c412c
Atomic Componentは、Atomic Designの進化系と表現されているケースもあったけど、見た限りは、適用事例の一つのように感じた。
実践:https://b3s.be-s.co.jp/programming-language/javascript/2989/
個人的な感想
小さくてシンプルな案件ならそのまま適用でもいいかも?
ある程度の規模以上は、たたき台として用いて、すぐに卒業するくらいの使い方が良さそう。
精細的技巧 (Exquisite techniques)
-
- 実装テクニック
setStateメソッドは、2種類の指定の仕方(便宜上、絶対値設定と、相対値設定とでも呼ぶか?)を使い分けよう
三項演算子よりもnullish coalescingがスマートな場合がある
{} unknown null は使い分けたい(他にもありそう
SyntheticEvent:元々のイベントを抑制して、自身のイベントを優先して動かす。
実装テクニック集
https://react-typescript-cheatsheet.netlify.app/
https://qiita.com/baby-degu/items/ea4eede60bbe9c63a348
Javascriptを読みやすくするテクニック:https://github.com/ryanmcdermott/clean-code-javascript
命名チートシート:https://github.com/kettanaito/naming-cheatsheet
cssテクニック集
https://blog.uhy.ooo/entry/2020-12-19/css-component-design/
https://github.com/alan2207/bulletproof-react/blob/master/docs/components-and-styling.md
性能テクニック集
https://qiita.com/teradonburi/items/5b8f79d26e1b319ac44f
最后
哎呀,信息量真是很大啊。
暂且以这个为基础开始试试看吧。
如果有时间的话,我会将实践结果写成文章。
如果有任何意见或指正,请一定告诉我!!!
以上 。