つのユースケースのために宣言的なAPIを犠牲にしないでください
15641 ワード
イマジン.あなたは反応成分を設計しています、そして、それは大きくなります.あなたは宣言的な方法で必要なすべてのユースケースをエレガントに扱うことができました.でも・・・あなたのデザインに適合しない新しいシナリオを考えると、レンチはあなたの美しいAPIにスローされます.グリッドを手動で再読み込みしたり、フォームをリセットするような命令的なことをする必要があります.あなたはユースケースの90 %のための完全なAPIを持っているが、この1つの小さな要件はそれをすべて破壊している.何をしますか.
私を信じて、そこに行ったことがある.それはしばらくの間気が狂っています、しかし、私はついにかなりよくそれを解決するパターンを思いつきました.お見せしましょう.
グリッドを作りましょう
自分のデータを取得するページンググリッドコンポーネントを作成しようとしているとしましょう.これは、Go - to - Gridコンポーネントとして会社の至る所で使用される予定です.したがって、開発者が実装するのを可能な限り簡単にしたいと思います.
我々はそれをセットアップした
ここにレンチが来る
その後、機能が追加されます
私たちは、状態を動かして、それ自身のフックに論理をフェッチします
分析のAPI
ステップに戻って、シナリオに基づいてこれらの2つのアプローチを分析しましょう.
最初の反復
The second iteration using the
シンプルなユースケースのためのコンポーネント専用APIと、より複雑なもののフックAPIを持ちたい.
つのAPI、1つのコンポーネント
我々が戻るならば
このパターンでは、両方のコンポーネントのAPIを持つことができます.つの異なる用法に戻って、彼らは両方を今すぐに使用して動作します
この場合、
フックの規則
今すぐあなたのpitchforksを出す前に言うと“オプションをフックを呼び出すことはできません!”私の言うことを聞きなさい.それがなぜ第一に規則であるかについて考えてください.状態が同期から出ないように、フックは常に同じ順序で呼ばれなければなりません.それで、それが意味するものはフックがいつも呼ばれなければならないということです、あるいは、それは決して呼ばれることができません.
我々の新しいAPIでは、開発者が条件付きで提供しているケースは決してありません
概要 すべてのユースケースで最も単純なAPIを生成するのは難しい宣言と命令的なAPIを混合することができます コンポーネントのロジックを制御し、デフォルトのプロップ値を作るためにフックを使用すると、命令と宣言のAPIが共存することができます
私を信じて、そこに行ったことがある.それはしばらくの間気が狂っています、しかし、私はついにかなりよくそれを解決するパターンを思いつきました.お見せしましょう.
グリッドを作りましょう
自分のデータを取得するページンググリッドコンポーネントを作成しようとしているとしましょう.これは、Go - to - Gridコンポーネントとして会社の至る所で使用される予定です.したがって、開発者が実装するのを可能な限り簡単にしたいと思います.
我々はそれをセットアップした
source
データを取得するためのpropuseEffect
ページ番号が変わるとき.function Grid({ source }) {
const [data, setData] = useState({ values: [], count: 0 });
const [page, setPage] = useState(1);
// fetch data on page change
useEffect(() => {
getData();
}, [page]);
function getData() {
// call the `source` prop to load the data
return source(page).then((results) => {
setData(results);
});
}
return (
// ...
);
}
次のように使われます:function PersonGrid() {
return (
<Grid
source={page =>
fetch(`/api/people?page=${page}`)
.then(res => res.json())
}
// ...
/>
);
}
これは本当に簡単なユースケースに最適です.開発者はインポートする必要がありますGrid
, パスするsource
, そして、それはちょうど働きます.ここにレンチが来る
その後、機能が追加されます
PersonGrid
ユーザーが新しい人々を追加することができます画面が、問題が発生します.The Grid
フェッチを制御し、新しい人が追加されていることを知りませんので、リロードすることを知りません.我々が必要とするものは、データを扱う外部の方法です.我々がそれをしなければならないことを再評価しましょう.私たちは、状態を動かして、それ自身のフックに論理をフェッチします
useGrid
, これはGrid
コンポーネントは本当に簡単です.その唯一の仕事は現在、データをinstance
プロップfunction useGrid({ source }) {
const [data, setData] = useState({ values: [], count: 0 });
const [page, setPage] = useState(1);
useEffect(() => {
getData();
}, [page]);
function getData() {
return source(page).then((results) => {
setData(results);
});
}
return {
data,
page
};
}
function Grid({ instance }) {
return (
// ...
);
}
我々の中でPersonGrid
コンポーネントは、フックでグリッドインスタンスを作成し、Grid
.function PersonGrid() {
const grid = useGrid({
source: page =>
fetch(`/api/people?page=${page}`)
.then(res => res.json())
});
return (
<Grid
instance={grid}
// ...
/>
);
}
我々のデータがそれ自身のフックで扱われて、それはまっすぐにreloadシナリオを作ります.function useGrid({ source }) {
const [data, setData] = useState({ values: [], count: 0 });
const [page, setPage] = useState(1);
useEffect(() => {
getData();
}, [page]);
function getData() {
return source(page).then((results) => {
setData(results);
});
}
return {
data,
page,
reload: getData
};
}
今私たちは人を追加した後PersonGrid
, 我々は、ちょうど電話する必要がありますgrid.reload()
.分析のAPI
ステップに戻って、シナリオに基づいてこれらの2つのアプローチを分析しましょう.
最初の反復
Grid
そのフェッチを内部的に扱うのは本当に使いやすい.これは、データの再読み込みシナリオに入ったときにのみ問題に実行されます.The second iteration using the
useGrid
フックは、データの再読み込みシナリオを簡単に、まだ基本的なユースケースをより複雑にした.開発者は両方をインポートする必要がありますuseGrid
and Grid
. コンポーネントAPIの表面積の増加は、特に単純な使用例のために考慮される必要がある.シンプルなユースケースのためのコンポーネント専用APIと、より複雑なもののフックAPIを持ちたい.
つのAPI、1つのコンポーネント
我々が戻るならば
Grid
コンポーネント、両方を含めることができますsource
and instance
小道具function Grid({
source,
instance = useGrid({ source })
}) {
// Any optional props that need to be used in here should come through the `useGrid` hook.
// `instance` will always exist, but the optional props may not.
return (
// ...
);
}
我々が得ている通知source
プロップとして、我々はそれを作成するために使用しているuseGrid
インスタンスのインスタンスinstance
プロップこのパターンでは、両方のコンポーネントのAPIを持つことができます.つの異なる用法に戻って、彼らは両方を今すぐに使用して動作します
Grid
コンポーネント.この場合、
instance
プロップsource
プロップは必要ありません.フックにあるので).function PersonGrid() {
const grid = useGrid({
source: page =>
fetch(`/api/people?page=${page}`)
.then(res => res.json())
});
return (
<Grid
instance={grid}
// ...
/>
);
}
この場合、source
prop(それはフードの下でインスタンスを構築します).function PersonGrid() {
return (
<Grid
source={page =>
fetch(`/api/people?page=${page}`)
.then(res => res.json())
}
// ...
/>
);
}
フックの規則
今すぐあなたのpitchforksを出す前に言うと“オプションをフックを呼び出すことはできません!”私の言うことを聞きなさい.それがなぜ第一に規則であるかについて考えてください.状態が同期から出ないように、フックは常に同じ順序で呼ばれなければなりません.それで、それが意味するものはフックがいつも呼ばれなければならないということです、あるいは、それは決して呼ばれることができません.
我々の新しいAPIでは、開発者が条件付きで提供しているケースは決してありません
instance
プロップそれらはいずれかを提供しますinstance
propを指定します.useGrid
使用されません、あるいは、彼らはsource
プロップ、意味useGrid
フックは常に呼ばれます.これはフックのルールを満たすが、あなたは他の方法を見てエスリントを指示する必要があります.概要
Reference
この問題について(つのユースケースのために宣言的なAPIを犠牲にしないでください), 我々は、より多くの情報をここで見つけました https://dev.to/derekmt12/don-t-sacrifice-your-declarative-api-for-one-use-case-a-react-pattern-for-conditional-hooks-2mboテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol