前情回顧書接上回,前面引出了在資料存在級聯的情況下,各下拉框之間的預設值及值變化的處理。簡單回顧一下: 場景是:
問題:
解決:
新的問題進一步實踐,會發現這種解決方式存在缺陷,在多級級聯的情況下,比如三個下拉框 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 預設值及資料級聯的使用
- Java實現資料庫和資料表的二級聯動Java資料庫
- C/C++ Qt 資料庫與ComBox多級聯動C++QT資料庫
- 基於layui的省市區三級聯動(資料互動)UI
- 符合 iview 資料規則的省市區三級聯動View
- 小資料二級聯動-封裝成一個二級聯動部分檢視封裝
- 容器雲資源資料關聯與資料聯動的難點和解決思路
- MySQL級聯複製中的資料同步(第二篇)MySql
- 優化資料庫的合理順序優化資料庫
- 多對多關聯 attach() 相同的資料包錯
- 資料庫的升級及遷移資料庫
- linux下向一個檔案中的某行插入資料的做法Linux
- 一個省市縣三級聯動的回顯(帶資料庫)資料庫
- 小程式:動態資料實現三級聯動選擇器
- MySQL 資料庫重置密碼MySql資料庫密碼
- 資料分享 — 省市區街道社群 5 級聯動資料 ---- 送演示 ---- 送服務端程式服務端
- 檢視oracle 資料庫中的級聯刪除(delete cascade)Oracle資料庫delete
- sql觸發器刪除資料庫中的級聯記錄SQL觸發器資料庫
- 合理選擇資料探勘工具(轉)
- Android版本升級同時Sqlite資料庫的升級及之前資料的保留AndroidSQLite資料庫
- .NET 百萬級 大資料插入、更新 ,支援多種資料庫大資料資料庫
- 細聊Concent & Recoil , 探索react資料流的新開發模式React模式
- 多資料來源與動態資料來源的權衡
- Java中的多資料來源管理:如何在單個應用中整合多資料庫Java資料庫
- 簡單的使用rman備份oracle資料庫的做法Oracle資料庫
- “物聯網”——更多的移動資料流量
- 資料庫事物、隔離等級及資料庫鎖機制資料庫
- Recoil Input 游標位置被重置到末尾的問題
- 合理的商品結構規劃–資料資訊圖
- Oracle中的資料字典技術及常用資料字典總結Oracle
- MyBatis 查詢資料時屬性中多對一的問題(多條資料對應一條資料)MyBatis
- 寶藏級BI資料視覺化功能|圖表聯動分析視覺化
- C語言 資料的位級表示及操作C語言
- 合理使用後設資料工具,解決大資料治理落地難點大資料
- SQL Server資料庫建立新使用者及關聯資料庫的方法教程SQLServer資料庫
- vue中select繫結多個值及資料回顯Vue
- 多級複製的資料不同步問題
- 幾行程式碼實現ListView的多級聯動——多級聯動就是如此簡單行程View