問題再現(xiàn)
項目的背景:采用 react 系列 + ES6 + webpack凡蜻。
今天編程時亲善,JavaScript 程序報了這樣的錯誤:Cannot use 'in' operator to search for...
肆糕,具體錯誤信息如下:
解決思路
坦白說藻懒,這樣的錯誤最難調試却邓。因為它并不指向你所寫的具體代碼镀琉,而是泛泛指向了 lib.js
文件(該文件通常是第三方的打包壓縮庫)峦嗤,你幾乎無法依據(jù)錯誤類型與錯誤指向來定位到實際編程中的錯誤位置。
怎么辦屋摔?
在沒有章法的規(guī)律可循時烁设,這個時候,只有去學習并借鑒羅胖的“死磕”精神了!
死磕步驟:
依據(jù)故障頁面以及錯誤信息装黑,定位到出錯的文件副瀑,這一點應該不難;
在出錯的頁面中恋谭,依次點擊調試糠睡,看一看在哪一步開始報錯 了!很關鍵疚颊!比如狈孔,一開始加載就出錯了,那就定位到 js 文件的初始化部位材义;點擊某個按鈕出錯了均抽,那就定位到該按鈕的對應事件代碼中;以此類推其掂。
在定位的代碼范圍內油挥,采用“折中法”,一點點注釋掉款熬,刷新頁面查看是否依然出錯喘漏,如果出錯,這說明注釋掉部分的代碼沒有問題华烟,放開注釋,繼續(xù)其他可疑的代碼部分持灰;如果沒有錯誤了盔夜,恭喜你,你的定位位置就更加精細化了堤魁!總體思路就是如此喂链,循環(huán)往復,相信妥泉,總會有“撥開云霧見朗朗青天”的歡喜的椭微!
定位問題
就拿我的這次經(jīng)歷來說,經(jīng)歷的半個多小時的折騰與波折(主要精力都花在了一個 js 文件里盲链,因為很容易的就能定位到文件級別的)蝇率,我終于定位到了錯誤的代碼塊,如下:
console.log('rendernerererer: ', schoolData)
const schoolNode = (
<Select style={{width: '100%'}} placeholder="請選擇所屬學校">
{ schoolData.length && schoolData.map((item, idx) => (
<Option key={idx} value={`${item.id}`}>{item.name}</Option>
)) }
</Select>
);
再看看刽沾,這塊代碼在控制臺中的執(zhí)行信息:
很顯然本慕,輸出了 renderererer
,并且從中侧漓,可以得知:此時的 schoolData
為空數(shù)組[]
锅尘。然后,緊接著布蔗,就是開頭前面給出的那個錯誤信息再現(xiàn)了L傥ァ@烁!
說明了什么顿乒?
這不就說明了议街,就是 console.log()
下面的代碼導致的這樣的錯誤嗎!
OK淆游,終于定位到錯誤的根源了傍睹!查到錯誤后,解決就應該是順水推舟的事情了犹菱,我總覺得拾稳!
解決問題
人們常犯的一個錯誤就在于:我們過高的估計了自己的能力,而同時又往往過低的估計了對手的實力腊脱!可不是么访得?在基于 react
框架的開發(fā)過程中,類似于
<Select style={{width: '100%'}} placeholder="請選擇所屬學校">
{ schoolData.length && schoolData.map((item, idx) => (
<Option key={idx} value={`${item.id}`}>{item.name}</Option>
)) }
</Select>
這樣的代碼陕凹,我書寫得太常見悍抑、太普遍、太通用了杜耙,而且之前好像都沒有出現(xiàn)過什么錯誤搜骡,尤其是像這樣令我摸不著頭腦的 bug 更是沒有。
那么佑女,這一次究竟怎么了呢记靡?
其間具體研習探索細節(jié),在此不表团驱。只說結論吧:應該是在 Select
標簽中摸吠,當 schoolData
為空數(shù)組時,即schoolData.length
為0
了嚎花,結果即為false
寸痢,導致后續(xù)的schoolData.map()
也不會執(zhí)行。這樣就導致了形如:<Select>{ undefined }</Select>
的渲染結果紊选。 最終啼止,就導致了Cannot use 'in' operator to search for 'value' in undefined
的錯誤!
<Select></Select>
中可以為 <Select><option value="1">選擇</option></Select>
兵罢,或者 null
族壳,但是當為 undefined
時就出現(xiàn)這樣的錯誤了!
OK趣些,下面給出最終修改后仿荆、可正確運行的版本一:
const schoolData = this.state.schoolList;
console.log('rendernerererer: ', schoolData)
const schoolNode = (
<Select style={{width: '100%'}} placeholder="請選擇所屬學校">
{ schoolData.length ? schoolData.map((item, idx) => (
<Option key={idx} value={`${item.id}`}>{item.name}</Option>
)) : <Option value=''>請選擇...</Option> }
</Select>
);
或者,下面的版本二也可行:
const schoolData = this.state.schoolList;
console.log('rendernerererer: ', schoolData)
const schoolNode = (
<Select style={{width: '100%'}} placeholder="請選擇所屬學校">
{ schoolData.length ? schoolData.map((item, idx) => (
<Option key={idx} value={`${item.id}`}>{item.name}</Option>
)) : null }
</Select>
);
結尾的話
謹以記錄一下我的 web 前端 JavaScript 開發(fā)編程的學習心得,以上也都是我自己的一點習想拢操,難免有所疏漏锦亦,乃至根本就是錯誤的見解。如有方家看出令境,還請指正杠园!謝謝您的閱讀!別忘了點贊呦~~
也歡迎光臨 我的github