我最近在我的 Typescript React 代碼中遇到了一個非常有趣的問題。我遇到的問題如下:
當從 websocket 連接接收到新的停止時,我會在我的Trip物件上觸發一個方法。updateStop該方法具有以下實作:
public updateStop(stop: PassTimeUpdate): Trip {
const stops = this.getStops();
const stopToUpdate = stops.find(s => s.userStopCode === stop.UserStopCode);
if(!stopToUpdate)
return this;
stopToUpdate.updateStop(stop);
return this;
}
該getStops方法具有以下實作:
public getStops(): IteneraryStop[] {
return this.itenaries.flatMap(i => i.stops);
}
該updateStop方法具有以下實作:
public updateStop(updatedStopData: PassTimeUpdate) {
console.log(`Updating stop: ${this.name} from ${this.tripStopStatus} to ${updatedStopData.TripStopStatus}`);
this.tripStopStatus = updatedStopData.TripStopStatus;
}
層次結構如下:Trip 有 Iteneraries 有 Stops。
現在我的問題來了,當我想比較以前版本的行程和新版本的行程時。
if(oldTrip.getStops() === updatedTrip.getStops())
顯然,這會導致錯誤,因為停靠點已更新,因此不一樣。但是,以下內容:
if(oldTrip === updatedTrip)
結果為真。我在互聯網上尋找某種“克隆”物件的方法,因為我認為問題在于物件的簽名匹配,即使它們的內容不一樣?
由于 oldTrip 和 updatedTrip 匹配,react 在呼叫 setTrip(updatedTrip) 時不會觸發 useEffect 鉤子,因為它認為 oldTrip 和 updatedTrip 是相同的。
什么是迫使旅行“不同”的好方法?我嘗試過使用某種internalID字串,每次updateStop執行該方法時都會更新它,但這仍然會導致相同的行為。
uj5u.com熱心網友回復:
我假設oldTrip并且updatedTrip是Trip. 聽起來您可能正在嘗試操作存盤在不同點的實體,oldTrip然后updatedTrip認為這些變數的比較將與以前不同。
你實際上在做什么比較同一個實體Trip。當您將實體放入 var 時,它不會復制它。它只是指向同一個指標。
比較是true, 因為 evenoldTrip只是指向同一個實體的指標。每當您使用 then 方法操作實體時,oldTrip也會發生變化,因為它只是指向實體的指標。當你比較它們時,JS 評估器會問“這些是同一個實體嗎”,這是真的。
此外,當您像這樣對任何物件(包括陣列、類的實體等)執行比較運算子時,它不會說“內容是否不同”。在第一個示例中,它每次都會回傳 false,因為在 JS
[1,2,3] == [1,2,3]中將再次回傳 false,因為它正在比較指標,這里有兩個新陣列在兩側初始化。它不會隱式比較內容。
人們落入這個陷阱的一個原因是,比較像字串、數字這樣的原語可以正常作業。但這些不是物件,因此您不是在比較參考,而是真正的潛在價值。更多資訊在這里。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/516228.html
上一篇:如何從Typescript中的Filter<T>訪問$and運算子,在Filter<T>作為引數傳入的方法中?
下一篇:打字稿事件發射器型別
