前情回顧書接上回,前面引出了在資料存在級聯的情況下,各下拉框之間的預設值及值變化的處理。簡單回顧一下: 場景是:
問題:
解決:
新的問題進一步實踐,會發現這種解決方式存在缺陷,在多級級聯的情況下,比如三個下拉框 A->B->C,A 決定 B, B 決定 C,按照這個解決思路,
這顯然不科學,非常冗餘。同時從元件解耦的角度來看,A,B 需要知道誰依賴了自己從而重置它們,這種耦合非常難以維護。 因此應該反過來,將解決問題的邏輯囿於元件自身才是科學的做法。 於是 A 不管其他,只管自己隨便隨便怎麼變化,B 中監聽 A 變化然後做出反應以重置自己,C 監聽 B 的變化以重置自己。這樣邏輯做到了內聚無耦合。 而之前文章中之所以沒用這種方式,是因為發現該方式具有滯後性,元件內部會停留在錯誤的值上渲染一次。 export function ZoneSelect() {
+ const region = useRecoilValue(regionState);
const zones = useRecoilValue(zonesState);
const [zone, setZone] = useRecoilState(zoneState);
+ console.log("zone:", zone.id);
+ useEffect(() => {
+ setZone(zones[0]);
+ }, [region]);
return (
<label htmlFor="zoneId">
…
</label>
);
}
這裡會先列印一次舊值,等 狀態的正確使用細思會發現,上面之所以會有這種錯誤是因為姿勢沒對,假若我們要使用可用區的值,應該在 useEffect(() => {
// do sth with zone
console.log("zone", zone.id);
}, [zone]);
此時列印就會得到正確的結果。 按照這個邏輯修正後的元件及聯動關係就成了: RegionSelect.tsx export function RegionSelect() {
const regions = useRecoilValue(regionsState);
const [region, setRegion] = useRecoilState(regionState);
return (
<label htmlFor="regionId">
Region:
<select
name="regionId"
id="regionId"
value={region.id}
onChange={(event) => {
const regionId = event.target.value;
const region = regions.find((region) => region.id === regionId);
setRegion(region!);
}}
>
{regions.map((region) => (
<option key={region.id} value={region.id}>
{region.id}
</option>
))}
</select>
</label>
);
}
ZoneSelect.tsx export function ZoneSelect() {
const zones = useRecoilValue(zonesState);
const [zone, setZone] = useRecoilState(zoneState);
const resetZone = useResetRecoilState(zoneState);
const region = useRecoilValue(regionState);
// region 變化後重置 zone
useEffect(() => {
resetZone();
}, [region, resetZone]);
useEffect(() => {
// do sth with zone
console.log("zone", zone.id);
}, [zone]);
return (
<label htmlFor="zoneId">
Zone:
<select
name="zoneId"
id="zoneId"
value={zone.id}
onChange={(event) => {
const zoneId = event.target.value;
const zone = zones.find((zone) => zone.id === zoneId);
setZone(zone!);
}}
>
{zones.map((zone) => (
<option key={zone.id} value={zone.id}>
{zone.id}
</option>
))}
</select>
</label>
);
}
優化資料的依賴關係進一步思考,導致可用區需要重置的直接原因其實並不是地域發生了變化,而是地域發生變化後,可用區下拉框的可選項發生了變化,亦即 export function ZoneSelect() {
const zones = useRecoilValue(zonesState);
const [zone, setZone] = useRecoilState(zoneState);
const resetZone = useResetRecoilState(zoneState);
useEffect(() => {
resetZone();
}, [resetZone, zones]);
useEffect(() => {
// do sth with zone
console.log("zone", zone.id);
}, [zone]);
return (
<label htmlFor="zoneId">
Zone:
<select
name="zoneId"
id="zoneId"
value={zone.id}
onChange={(event) => {
const zoneId = event.target.value;
const zone = zones.find((zone) => zone.id === zoneId);
setZone(zone!);
}}
>
{zones.map((zone) => (
<option key={zone.id} value={zone.id}>
{zone.id}
</option>
))}
</select>
</label>
);
}
這樣一來,元件內部就清爽多了,只有自身相關的資料,甚至都去掉了對
|
The text was updated successfully, but these errors were encountered: |
Recoil 中多級資料聯動及資料重置的合理做法
相關文章
- Recoil 預設值及資料級聯的使用
- C/C++ Qt 資料庫與ComBox多級聯動C++QT資料庫
- 基於layui的省市區三級聯動(資料互動)UI
- 符合 iview 資料規則的省市區三級聯動View
- 小資料二級聯動-封裝成一個二級聯動部分檢視封裝
- 容器雲資源資料關聯與資料聯動的難點和解決思路
- 多對多關聯 attach() 相同的資料包錯
- MySQL 資料庫重置密碼MySql資料庫密碼
- 細聊Concent & Recoil , 探索react資料流的新開發模式React模式
- .NET 百萬級 大資料插入、更新 ,支援多種資料庫大資料資料庫
- 資料分享 — 省市區街道社群 5 級聯動資料 ---- 送演示 ---- 送服務端程式服務端
- 小程式:動態資料實現三級聯動選擇器
- 多資料來源與動態資料來源的權衡
- Java中的多資料來源管理:如何在單個應用中整合多資料庫Java資料庫
- vue中select繫結多個值及資料回顯Vue
- MyBatis 查詢資料時屬性中多對一的問題(多條資料對應一條資料)MyBatis
- Recoil Input 游標位置被重置到末尾的問題
- SQL Server資料庫建立新使用者及關聯資料庫的方法教程SQLServer資料庫
- 寶藏級BI資料視覺化功能|圖表聯動分析視覺化
- 靜默方式安裝、升級oracle(三): 升級資料庫軟體及資料庫Oracle資料庫
- 把多個資料夾中的檔案批量放到一個資料夾
- 全程解析,MyBatis在SpringBoot中的動態多資料來源配置MyBatisSpring Boot
- 使用cglib實現資料庫框架的級聯查詢CGLib資料庫框架
- Flutter學習(8)——CheckBox多選框使用及動態更改多選框資料Flutter
- 資料庫升級之-Dataguard滾動升級資料庫
- 資料庫升級之-資料泵資料庫
- windows系統下 重置mysql資料庫的密碼WindowsMySql資料庫密碼
- 2024年及以後大資料的頂級趨勢大資料
- Oracle資料庫中的多種SCN彙總Oracle資料庫
- Laravel-admin 三級聯動 or 多級聯動 編輯 and 新建Laravel
- jeefast框架 修改的下拉框三級聯動預設顯示後臺資料AST框架
- 資料治理與資料分類分級!
- 物聯網的資料方案
- 資料庫多對多表關係資料資料庫
- EF 中多個資料庫遷移資料庫
- 多對多關聯的時候,怎麼返回中間表的資料集合
- sql 多組條資料取最新的一條資料SQL
- 多個異構資料庫如何關聯查詢資料庫