前端開發中遇到的Error們(持續更新......)

語言: CN / TW / HK

theme: cyanosis

持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第4天,點選檢視活動詳情

本文僅記錄自己在日常開發過程中遇到的各種報錯和資料異常問題。

React專案

| 問題 | 排查原因 | 解決方案 | | --- | --- | --- | | react的ts模式下,安裝後依賴報錯:無法找到模組 image.png| ts不能識別安裝的依賴引用 | 在dev依賴安裝對應模組依賴的@types格式 或者自定義宣告對應的.d.ts檔案 | | Objects are not valid as a React child | 出現的地方不止一處,都是把一個object當做陣列了,因為React的花括號渲染children時必須是array形式。 | 排查出現問題的檔案中傳參的正確性即可。| |TypeError: Cannot read properties of null (reading '1') |類似讀不到null或者undefined的屬性值,一般上就是物件傳成了空,比如 info.name, 你的info如果沒有初始化或者通過某種手段設定為了空,就會報這個錯誤 | 1. 改寫 info?.name
2. 如果是props值,使用之前需判空;如果是本元件內的變數,可以useState({}), 在setInfo的時候可以這樣寫setInfo(data \|\| {})| |Uncaught Error: You are trying to create a styled element with an undefined component. You may have forgotten to import it. | 使用styled對元件設定樣式時,元件傳了空| const SelectInput = styled(Input.Search)中核對Input.Search不為空即可 | |A cross-origin error was thrown. React doesn't have access to the actual error object in development|這種錯誤一般是 JSON.parse()傳入了空|-| |TypeError: rawData.some is not a function|使用了ant design的Table元件,官方要求dataSource應為陣列, 實際上傳了{}|-| |Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.|元件銷燬時非同步還沒執行完畢,在非同步執行完後發現找不到宿主了。檢查各個元件,確保在元件銷燬之後不在呼叫非同步|元件載入時設定isMounted = ture, 元件銷燬時設定isMounted = false, 在必要的非同步回撥的地方加上isMounted判斷即可| |解決js-xslx庫匯出excel時,解析日期時間對不上的問題|比較小眾的問題,一個excel匯出的外掛,匯出的時間格式總是與實際時間有誤差,應該是時區不統一造成的|安裝一個依賴yarn add ssf,在匯出的格式化中寫入:moment(new Date(SSF.format("YYYY-MM-DD HH:MM:ss", item['失效時間']) + " GMT+0800")).format('YYYY-MM-DD HH:mm:ss') | |Warning: Encountered two children with the same key...|同一個迴圈列表裡兩個並列的item使用了相同的Key|使用uuid代替,或者在保證安全的前提下使用index代替| |Warning: [antd: Form.Item] name is only used for validate React element. If you are using Form.Item as layout display, please remove name instead.|antd的form中表單元素要加上name屬性,非表單元素不要加|-| |Maximum update depth exceeded.|可能原因:在render期間setState造成的超量賦值操作,逐一排查,肯定有呼叫死迴圈 : 父元件render => 引數變化 => 觸發子元件useEffect => 引數變化 => 回撥父元件引起父元件該引數變化|-| |彈窗元件中也會有 Can't perform a React state update on an unmounted component|我們不能在元件銷燬後設置state,防止出現記憶體洩漏的情況|在彈窗setVisible(false)後或者元件銷燬函式中,不要再setState| |Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.|寫的元件忘記 export啦|-| |npm run dev 報錯:Error: error:0308010C:digital envelope routines::unsupported|node版本不合適,一般要將降低版本|-| |index.tsx:24 Uncaught Error: [undefined] is not a \<Route> component. All component children of \<Routes> must be a \<Route> or \<React.Fragment>|react-router-dom使用時的問題|\不要放到\<Route>裡, 直接放到\下就可以了| |ReactDOM.render is no longer supported in React 18|升級到react18後,ReactDOM下不再有render這個方法了|使用ReactDOM.createRoot代替| |antd的報錯: Warning: Instance created by useForm is not connected to any Form element. Forget to pass form prop?|這種情況一般是在Modal裡的Form出現,一般原因是在初始化鉤子呼叫form.setFieldsValue({})時,form還未來得及關聯到

元素上|給Modal元件新增forceRender屬性| |類式元件中Uncaught SyntaxError: embedded: Unexpected token .| token什麼也沒有,說明是state初始化問題 | 直接寫 state = {}是有問題的, 應該放在constructor中 |

Angular專案

開發報錯1:No component factory found for . Did you add it to @NgModule.entryComponents
排查原因 ng8-的版本,動態元件需要在entryComponents裡宣告
解決

同原因


開發報錯2:ERROR TypeError: this.suiTableData.slice is not a function
排查原因 前端比較常見的問題,suiTableData作為元件input的資料,傳了個空
解決

同原因


開發報錯3:Type 'Map<string, string>' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.
排查原因 這是ts遍歷map會出現的問題,下面給出兩種解決辦法
解決

```ts //1 for(let [a,b] of Array.from( map.keys()) ) { console.log(a + ' ' + b); }

//2 map.forEach((value: string, key: string) => { console.log(key, value); }); ```


開發報錯4:No value accessor for form control with name: 'unitSelect'
排查原因 自定義的表單元件在ngForm中不受控
解決

ts // 在表單中加入ngDefaultControl <sui-select name="unitSelect" [(ngModel)]="calcIntervalUnit" ngDefaultControl>

開發報錯5:core.js:7187 ERROR Error: Uncaught (in promise): Error: Unexpected value 'undefined' declared by the module 'StreamDetailModule'
排查原因 表面上是module引了個寂寞,實際上可能是重複引入了。
解決

ts //1. 父子兩個index頁面重複引用了detail-list元件 //2. 還可能的其他問題: import 時多寫了一個逗號


單測報錯1:An error was thrown in afterAll\nUncaught:Cannot convert undefined or null to object thrown
排查原因 FedAuthService的注入有問題

原寫法: ts fetchTenantDetail() { this.tenantService.getTenantDetail(this.tenantName) .subscribe((tenant: TenantDetail) => { this.tenant = tenant; this.attrs = Object.entries(this.tenant && this.tenant.attributes); }); } spec.ts { provide: FedAuthService, useValue: { isAuthenticated () { return observableOf(); }, isLoggedIn() { return observableOf(); }, purge() { return observableOf(); } } } 一行一行註釋原來的component的邏輯程式碼,看是哪一行引入導致的錯誤,發現註釋掉this.fetchTenantDetail()就不會報錯了。進入該方法一層一層看,最終定位: ```ts //括號裡的可能為undefined Object.entries(this.tenant && this.tenant.attributes)

```

解決

```ts //改為 this.attrs = (this.tenant && this.tenant.attributes) ? Object.entries(this.tenant && this.tenant.attributes) : [];

// 或者在mock資料裡給this.tenant.attributes附上初值。 ```


單測報錯2:TenantDetailAuthSourceComponent should registerAuthSource TypeError: this.modalService.registerAuthSourceModal is not a function
排查原因 該函式沒有mock返回值
解決

```ts { provide: TenantModalsService, userClass: TenantModalsServiceStub },

class TenantModalsServiceStub { deleteTenantModal() { return observableOf(); } registerAuthSourceModal() { return observableOf(); } editAuthSourceModal() { return observableOf(); } } ```


單測報錯3:TranslateModule報錯:Invalid provider for the NgModule 'DynamicTestModule' - only instances of Provider and Type are allowed\
排查原因 測試用的module注入問題

查詢網址Invalid provider for the NgModule找到解決方案。

解決

```ts TranslateModule.forRoot({ loader: { provider: TranslateLoader, useClass: (translateFactory) } })

// Use useFactory instead of useClass. Use provide instead of provider. // Use @ngx-translate/core instead of ng2-translate ```


單測報錯4:There is no directive with "exportAs" set to "ngForm
排查原因 缺少FormsModule
解決

```ts //在測試類中引入 FormsModule import { FormsModule } from '@angular/forms';

TestBed.configureTestingModule({ schemas: [NO_ERRORS_SCHEMA], imports: [ MockModule, FormsModule ], declarations: [ ResourceMetricPropertyTableDesignComponent, TranslatePipeStub, ] }) ```