摘要:我們常常會收到一些有趣的問題,但大多數(shù)問題都是常見問題。我創(chuàng)建這個(gè)資源為了幫助學(xué)習(xí)者遇到這些常見的問題時(shí)提供一定幫助。這些是表示沒有任何子節(jié)點(diǎn)的元素的標(biāo)記。不綁定處理程序方法我把這個(gè)留到最后,因?yàn)檫@是一個(gè)大問題,一個(gè)很常見的問題。
在 jsComplete,我們管理一個(gè)專門用于幫助編程學(xué)習(xí)者 slack 帳戶。我們常常會收到一些有趣的問題,但大多數(shù)問題都是常見問題。 我創(chuàng)建這個(gè)資源為了幫助 React.js學(xué)習(xí)者遇到這些常見的問題時(shí)提供一定幫助。在這里可以快速找到一些常見問題的解決方案,而不是一,遍又一遍去找解決方法,我會持續(xù)更新這些常見的問題。
想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你!
1. 組件的名稱開頭要大寫React 組件名稱必須具有以大寫字母開頭。
如果組件名稱不以大寫字母開頭,則組件使用將被視為內(nèi)置元素,例如 div 或 span。
例如:
class greeting extends React.Component { // ... }
如果嘗試渲染
Warning: The tagis unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.
這里更大的問題是把組件命名為 button 或 img。 React 會忽略你的組件,只是渲染一個(gè)普通 HTML button 或 img 標(biāo)簽。
注意上面沒有渲染 “My Awesome Button” 和 React 剛剛呈現(xiàn)的空 HTML 按鈕元素。 在這種情況下,React 不會警告你。
2.使用單引號而不是反引號用反引號(`…`)創(chuàng)建的字符串與用單引號("…")創(chuàng)建的字符串不同。
在大多數(shù)鍵盤上,可以使用 tab 鍵上方的鍵來輸入用反引號( ` )字符。
當(dāng)需要在字符串中包含動(dòng)態(tài)表達(dá)式時(shí),使用反引號創(chuàng)建一個(gè)字符串(不需要使用字符串連接)。
`This is a string template literal that can include expressions` "This is just a string, you cannot include expressions here"
假設(shè)你想要一個(gè)始終報(bào)告當(dāng)前時(shí)間的字符串:
“Time is ...”
// Current time string const time = new Date().toLocaleTimeString(); // 使用普通字符串(單引號或雙引號)時(shí),需要使用字符串連接: "Time is " + time // 在使用反引號時(shí),可以使用 ${} 在字符串中注入時(shí)間 `Time is ${time}`
此外,反引號還聲明一個(gè)字符串時(shí),可以創(chuàng)建一個(gè)跨多行的字符串:
const template = `I CAN SPAN Multiple Lines`;
常規(guī)字符串不能這樣做。
3. 使用 React.PropTypesPropTypes 對象已從 React 中刪除。 其過去是以 React.PropTypes 的形式被使用,但不能再使用它了。
相應(yīng)的,你需要:
npm install prop-types
import PropTypes from "prop-types"
然后就可以使用它啦,如: PropTypes.string 。
如果你錯(cuò)誤地使用了 React.PropTypes,會得到這樣的錯(cuò)誤提示:
TypeError: Cannot read property "string" of undefined4. 沒有使用指南里指定的版本
在看或閱讀有關(guān)代碼的內(nèi)容以及使用指南里的例子時(shí),確保你使用的庫版本與例子的里的版本是一致的。一般使用最新版本是沒有問題,但是如果內(nèi)容過時(shí),你可能會遇到一些棄用問題。
為了安全起見,請使用主干版本。 例如,如果教程里使用的是 React 16,自己就不要使用 React 15 進(jìn)行開發(fā)了。
這對 Node.js 也很重要。如果使用舊版本的 Node,會遇到一系列問題。 例如,如果你正在看一些教程,這些教程使用了 Object.values,而你現(xiàn)在用 Node 6.x,那個(gè)版本此方法是不存在的。 你需要 Node 7.x 或更高版本。
5. 令人困惑的函數(shù)與類你能看出下面的代碼有什么問題嗎?
class Numbers extends React.Component { const arrayOfNumbers = _.range(1, 10); // ... }
上面的代碼是無效的,因?yàn)樵?JavaScript 類的內(nèi)部,不能隨意定義變量,只能使用規(guī)定的語法定義方法和屬性。
這有點(diǎn)令人困惑,因?yàn)轭愓Z法中使用的{}看起來像塊級作用域,但它并不是。
在一個(gè)由函數(shù)構(gòu)成的組件里,你就可以想怎么搞就怎么搞:
// Totally Okay: const Number = (props) => { const arrayOfNumbers = _.range(1, 10); // ... };6. 將數(shù)字作為字符串傳遞
你可以通過 prop 屬性傳遞一個(gè)字符串:
如果需要傳遞一個(gè)數(shù)值,不要使用字符串:
// 不要這樣做
相反,使用花括號傳遞一個(gè)實(shí)際的數(shù)值:
在 Greeting 組件中使用 {7},this.props.counter 就被賦值為數(shù)字 7 ,并且可以對其進(jìn)行數(shù)學(xué)運(yùn)算。 如果將其作為“7”傳遞,然后將其視為數(shù)字,則可能會遇到意外結(jié)果。
7. 忘記了另外一個(gè) app 在用同樣的端口要運(yùn)行 web 服務(wù)器,需要使用主機(jī)(如 127.0.0.1 )和端口(如 8080)使服務(wù)器偵聽有效 http 地址上的請求。
一旦成功運(yùn)行,web 服務(wù)器就占據(jù)了那個(gè)端口,你就不能讓這個(gè)端口它用,端口會被占用。
如果你嘗試在另一個(gè)終端上運(yùn)行相同的服務(wù)器,將會得到端口被占用的錯(cuò)誤提示,如下:
Error: listen EADDRINUSE 127.0.0.1:8080
請注意,有時(shí) Web 服務(wù)器可能在后臺運(yùn)行或在分離的屏幕/tmux 會話中運(yùn)行。你看不到,但它仍然占據(jù)了端口。 要重新啟動(dòng)服務(wù)器,需要“殺死”仍在運(yùn)行的服務(wù)器。
要識別使用某個(gè)端口的進(jìn)程,可以使用 ps 之類的命令(以及關(guān)于應(yīng)用程序的grep),或者如果你知道端口號,則可以使用 lsof 命令:
lsof -i :80808. 忘記創(chuàng)建環(huán)境變量
有些項(xiàng)目依賴于 shell 環(huán)境變量的存在才能啟動(dòng)。 如果在沒有所需環(huán)境變量的情況下運(yùn)行這些項(xiàng)目,它們將嘗試為它們使用未定義的值,并可能會給你一些神秘的錯(cuò)誤。
例如,如果項(xiàng)目連接到像 MongoDB 這樣的數(shù)據(jù)庫,則可能會使用像 process.env.MONGO_URI這樣的環(huán)境變量來連接它。 這允許項(xiàng)目與不同環(huán)境中的不同MongoDB 實(shí)例一起使用。
要在本地運(yùn)行連接到 MongoDB 的項(xiàng)目,首先必須導(dǎo)出 MONGO_URI 環(huán)境變量。 例如,如果你在端口 27017 上運(yùn)行本地 MongoDB,則需要在運(yùn)行項(xiàng)目之前執(zhí)行此操作:
export MONGO_URI="mongodb://localhost:27017/mydb"
你可以 grep 項(xiàng)目源代碼,找到 process.env 來查清楚其運(yùn)行正常所需要的環(huán)境變量。
9. 把花括號{}和圓括號()搞混不要用:
return { something(); };
這樣用:
return ( something(); );
第一個(gè)將嘗試(并且會失敗)返回一個(gè)對象,而第二個(gè)將正確調(diào)用 something() 函數(shù)并返回該函數(shù)返回的內(nèi)容。
因?yàn)?JSX 中的任何
這個(gè)問題在箭頭函數(shù)的縮寫語法中也很常見。
不要用:
const Greeting = () => {Hello World};
這樣用:
const Greeting = () => (Hello World);
當(dāng)你使用帶有箭頭函數(shù)的中括號時(shí),你就新起了一個(gè)函數(shù)的作用域。箭頭函數(shù)的縮寫語法不用中括號。
10. 不使用圓括號包裝對象當(dāng)你想要?jiǎng)?chuàng)建一個(gè)返回普通對象的箭頭函數(shù)時(shí),上面的花括號和圓括號問題也會讓你感到困惑。
不要用:
const myAction = () => { type: "DO_THIS" };
這樣用:
const myAction = () => ({ type: "DO_THIS"});
如果沒有把對象包裹在圓括號里,你就不能使用縮寫語法。實(shí)際上你會給字符串定義一個(gè)標(biāo)簽。
這在 setState 方法的 updater 函數(shù)中很常見,因?yàn)樗枰祷匾粋€(gè)對象。 如果要使用箭頭函數(shù)語法,則需要用括號包裝該對象。
不要用:
this.setState(prevState => { answer: 42 });
這樣用:
this.setState(prevState => ({ answer: 42 }));11. 沒有正確使用API元素和屬性的大小寫
使用 React.Component,而不是 React.component。 使用 componentDidMount,而不是 ComponentDidMount。使用 ReactDOM,而不是ReactDom。
請注意需要的 API 大小寫。 如果使用不正確的大小寫,得到的錯(cuò)誤信息可能不會很明確。
從 react 和 react-dom 導(dǎo)入時(shí),確保引入正確的名稱,并且使用的內(nèi)容與引入完全相同,ESLint 可以幫助你指出未使用的內(nèi)容。
在處理組件屬性時(shí)也會遇到這種問題:
// 在組件內(nèi)部,你需要使用 props.userName 來獲取傳入的值
如果你沒有使用 props.userName,而是 props.username 或 props.UserName,你會相當(dāng)于用了一個(gè) undefined 的值。需要特別留意下這點(diǎn),當(dāng)然更好的是配置 ESLint,它也能指出這些問題。
12. 將 state 對象與實(shí)例屬性搞混在類組件中,可以定義本地 state 對象,然后使用 this 訪問它:
class Greeting extends React.Component { state = { name: "World", }; render() { return `Hello ${this.state.name}`; } }
以上代碼會輸出 “Hello World”。
除 state 之外,你還可以定義其它本地實(shí)例屬性。
class Greeting extends React.Component { user = { name: "World", }; render() { return `Hello ${this.user.name}`; } }
以上代碼也會輸出 “Hello World”。
state 實(shí)例屬性是一個(gè)特殊屬性,因?yàn)?React 會管理它。 你只能通過 setState 更改它,當(dāng)你這樣做時(shí) React 會做出響應(yīng)。
然而,定義的所有其他實(shí)例屬性對渲染算法沒有影響。 你可以根據(jù)需要在上面的示例中更改this.user,并且 React 不會在React中觸發(fā)渲染機(jī)制。
13. 將在閉合標(biāo)簽里放錯(cuò) / 字符。不可否認(rèn),有時(shí)你可以使用
在 HTML 中,有一種稱為“自閉合標(biāo)簽”(AKA void tag)。這些是表示沒有任何子節(jié)點(diǎn)的元素的標(biāo)記。例如,img 標(biāo)簽是一個(gè)自閉合標(biāo)簽:
// 不必使用
以下方式是非法的:
// 錯(cuò)誤
如果放錯(cuò)放了 / 字符的位置,將收到如下錯(cuò)誤:
Syntax error: Unterminated JSX contents14. 假設(shè) import/export 起作用
import/export 特性是 JavaScript 中的官方功能(自2015年起)。 其只是 ES2015 的特性,并且還沒有在流行瀏覽器和最新版 Node 里面被完整支持。
React 項(xiàng)目的流行配置使用 Webpack 和 Babel。 兩者都允許使用此特性并將其編譯為所有瀏覽器都能理解的內(nèi)容。 只有工作流中有 Webpack 或 Babel 之類的轉(zhuǎn)譯工具,才能使用 import/export。
但是,在 React 打包應(yīng)用程序中 import/export 不意味著可以隨意使用它們! 例如,如果你還通過最新的 Node 進(jìn)行服務(wù)器端渲染,會行不通,你很可能會收到“unexpected token” 錯(cuò)誤。
要讓 Node 理解 import/export(如果你在前端使用它們就是你需要了解它們,并且也想要做 SSR 渲染的話),你需要有可以編譯其的 Babel preset(像是_env_ preset),才能在Node 端運(yùn)行。 你可以在開發(fā)時(shí)使用像 pm2_、 _nodemon 和 _babel-watch_的工具做到這點(diǎn),,并在每次更改內(nèi)容時(shí)重新啟動(dòng) Node。
15. 不綁定處理程序方法我把這個(gè)留到最后,因?yàn)檫@是一個(gè)大問題,一個(gè)很常見的問題。
你可以在 React 組件中定義類方法,然后在組件的 render 方法中使用它們。 例如:
class Greeting extends React.Component { whoIsThis() { console.dir(this); // "this" is the caller of whoIsThis return "World"; } render() { return `Hello ${this.whoIsThis()}`; } } ReactDOM.render(, mountNode);
我在 render 里以 this.whoIsThis 的方式調(diào)用 whoIsThis 方法,因?yàn)樵?render中,this 關(guān)鍵字指的是與表示組件的 DOM 元素關(guān)聯(lián)的組件實(shí)例。
內(nèi)部 React 確保其類方法中的 “this” 指向?qū)嵗?但是,當(dāng)你使用 whoIsThis 方法的引用時(shí),JavaScript 不會自動(dòng)綁定實(shí)例。
whoIsThis 方法中的 console.dir 可以正確告訴我們當(dāng)前組件實(shí)例,因?yàn)樵摲椒ㄊ鞘褂蔑@式調(diào)用方(this)直接從 render 方法調(diào)用的。 執(zhí)行上面的代碼時(shí),在控制臺中看到Greeting 對象:
然而,當(dāng)在延遲執(zhí)行通道,例如事件處理里執(zhí)行同樣方法時(shí),調(diào)用對象將不再是顯性的,console.dir 也不會打印當(dāng)前組件實(shí)例。
在上面的代碼中,當(dāng)單擊字符串時(shí),React 會調(diào)用 whoIsThis 方法,但它不會讓你訪問組件實(shí)例。 這就是我們點(diǎn)擊字符串時(shí)得到 undefined 的原因。 如果類方法需要訪問像this.props 和 this.state 這樣的屬性,這會是一個(gè)問題,因?yàn)樗拘胁煌ā?/p>
對于這個(gè)問題有很多解決方案??梢詫⒎椒òb在內(nèi)聯(lián)函數(shù)中,或使用 .bind 來改變 this 指向。 對于不經(jīng)常更新的組件,兩者都可以。
還可以通過在類的構(gòu)造函數(shù)中而不是在 render 方法中執(zhí)行來優(yōu)化 bind 方法。 但是,此方法的最佳解決方案是通過 Babel 來使用 ECMAScript 類字段我(目前還是stage-3),這樣對于處理程序只需使用箭頭函數(shù)就可以了:
class Greeting extends React.Component { whoIsThis = () => { console.dir(this); } render() { return (Hello World); } }
這樣會和預(yù)期一樣執(zhí)行:
代碼部署后可能存在的BUG沒法實(shí)時(shí)知道,事后為了解決這些BUG,花了大量的時(shí)間進(jìn)行l(wèi)og 調(diào)試,這邊順便給大家推薦一個(gè)好用的BUG監(jiān)控工具 Fundebug。
原文:
https://edgecoders.com/react-...
你的點(diǎn)贊是我持續(xù)分享好東西的動(dòng)力,歡迎點(diǎn)贊!
歡迎加入前端大家庭,里面會經(jīng)常分享一些技術(shù)資源。文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/101659.html
摘要:因?yàn)楣ぷ髦幸恢痹谑褂?,也一直以來想總結(jié)一下自己關(guān)于的一些知識經(jīng)驗(yàn)。于是把一些想法慢慢整理書寫下來,做成一本開源免費(fèi)專業(yè)簡單的入門級別的小書,提供給社區(qū)。本書的后續(xù)可能會做成視頻版本,敬請期待。本作品采用署名禁止演繹國際許可協(xié)議進(jìn)行許可 React.js 小書 本文作者:胡子大哈本文原文:React.js 小書 轉(zhuǎn)載請注明出處,保留原文鏈接以及作者信息 在線閱讀:http://huzi...
摘要:零基礎(chǔ)學(xué)了快兩個(gè)月的了,所謂的基礎(chǔ)是指完全不懂,,還有任何相關(guān)概念,等等。這里說服務(wù)器渲染,是誤打誤撞了,我剛只是想把換掉而已。由負(fù)責(zé)將翻譯成對應(yīng)的文件順帶解決了語法問題。 零基礎(chǔ)學(xué)了快兩個(gè)月的React了(React-native + React.js),所謂的000基礎(chǔ)是指完全不懂JS,CSS,HTML5還有任何相關(guān)概念Dom,Server rendering等等。PS:這里說服務(wù)...
摘要:在不需要手動(dòng)調(diào)用瀏覽器原生的進(jìn)行事件監(jiān)聽。沒有經(jīng)過特殊處理的話,這些的事件監(jiān)聽只能用在普通的的標(biāo)簽上,而不能用在組件標(biāo)簽上。的事件監(jiān)聽方法需要手動(dòng)到當(dāng)前實(shí)例,這種模式在中非常常用。下一節(jié)中我們將介紹小書組件的和。 React.js 小書 Lesson9 - 事件監(jiān)聽 本文作者:胡子大哈本文原文:http://huziketang.com/books/react/lesson9 轉(zhuǎn)載請...
摘要:譯者按最近依舊如火如荼相信大家都躍躍欲試我們團(tuán)隊(duì)也開始在領(lǐng)域有所嘗試年應(yīng)該是逐漸走向成熟的一年讓我們一起來看看國外的開發(fā)者們都總結(jié)了哪些最佳實(shí)踐年在全世界都有很多關(guān)于新的更新和開發(fā)者大會的討論關(guān)于去年的重要事件請參考那么年最有趣的問題來了我 譯者按:最近React(web/native)依舊如火如荼,相信大家都躍躍欲試,我們團(tuán)隊(duì)也開始在React領(lǐng)域有所嘗試. 2016年應(yīng)該是Reac...
摘要:,谷歌給的一份性能指南和最佳實(shí)踐。目前而言,前端社區(qū)有三大框架和。隨后重點(diǎn)講述了和兩大前端框架,給出了大量的文章教程和相關(guān)資源列表。我認(rèn)為,使用函數(shù)式編程方式,更加符合后端程序員的思路,而是更符合前端工程師習(xí)慣的框架。 showImg(https://segmentfault.com/img/bVbjQAM?w=1142&h=640); 這個(gè)是我訂閱 陳皓老師在極客上的專欄《左耳聽風(fēng)》...
摘要:,谷歌給的一份性能指南和最佳實(shí)踐。目前而言,前端社區(qū)有三大框架和。隨后重點(diǎn)講述了和兩大前端框架,給出了大量的文章教程和相關(guān)資源列表。我認(rèn)為,使用函數(shù)式編程方式,更加符合后端程序員的思路,而是更符合前端工程師習(xí)慣的框架。 showImg(https://segmentfault.com/img/bVbjQAM?w=1142&h=640); 這個(gè)是我訂閱 陳皓老師在極客上的專欄《左耳聽風(fēng)》...
閱讀 627·2021-08-31 09:45
閱讀 1725·2021-08-11 11:19
閱讀 953·2019-08-30 15:55
閱讀 904·2019-08-30 10:52
閱讀 2930·2019-08-29 13:11
閱讀 2997·2019-08-23 17:08
閱讀 2902·2019-08-23 15:11
閱讀 3142·2019-08-23 14:33