1. 生命周期
初始化階段
constructor
構(gòu)造函數(shù)getDefaultProps
props
默認(rèn)值getInitialState
state
默認(rèn)值掛載階段
componentWillMount
組件初始化渲染前調(diào)用render
組件渲染componentDidMount
組件掛載到DOM
后調(diào)用更新階段
componentWillReceiveProps
組件將要接收新props
前調(diào)用shouldComponentUpdate
組件是否需要更新componentWillUpdate
組件更新前調(diào)用render
組件渲染componentDidUpdate
組件更新后調(diào)用卸載階段
componentWillUnmount
組件卸載前調(diào)用
2. 生命周期
初始化階段
constructor
構(gòu)造函數(shù)getDefaultProps
props
默認(rèn)值getInitialState
state
默認(rèn)值掛載階段
staticgetDerivedStateFromProps(props,state)
render
componentDidMount
getDerivedStateFromProps:組件每次被 rerender
的時(shí)候卖毁,包括在組件構(gòu)建之后(虛擬 dom
之后踪区,實(shí)際 dom
掛載之前),每次獲取新的 props
或 state
之后褒傅;每次接收新的props之后都會(huì)返回一個(gè)對(duì)象作為新的 state
捧存,返回null則說(shuō)明不需要更新 state
粪躬;配合 componentDidUpdate
,可以覆蓋 componentWillReceiveProps
的所有用法
更新階段
staticgetDerivedStateFromProps(props,state)
shouldComponentUpdate
render
getSnapshotBeforeUpdate(prevProps,prevState)
componentDidUpdate
getSnapshotBeforeUpdate:觸發(fā)時(shí)間:
update發(fā)生的時(shí)候昔穴,在
render之后镰官,在組件
dom渲染之前;返回一個(gè)值吗货,作為
componentDidUpdate的第三個(gè)參數(shù)泳唠;配合
componentDidUpdate, 可以覆蓋
componentWillUpdate`的所有用法
卸載階段
componentWillUnmount
錯(cuò)誤處理
componentDidCatch
React16
新的生命周期棄用了 componentWillMount、componentWillReceivePorps宙搬,componentWillUpdate
新增了 getDerivedStateFromProps笨腥、getSnapshotBeforeUpdate
來(lái)代替棄用的三個(gè)鉤子函數(shù)。
React16并沒(méi)有刪除這三個(gè)鉤子函數(shù)勇垛,但是不能和新增的鉤子函數(shù)混用脖母,
React17將會(huì)刪除這三個(gè)鉤子函數(shù),新增了對(duì)錯(cuò)誤的處理(
componentDidCatch`)
3. setState是同步的還是異步的窥摄?
- 生命周期和合成事件中
在 React
的生命周期和合成事件中镶奉, React
仍然處于他的更新機(jī)制中,這時(shí)無(wú)論調(diào)用多少次 setState
,都會(huì)不會(huì)立即執(zhí)行更新哨苛,而是將要更新的·存入 _pendingStateQueue
鸽凶,將要更新的組件存入 dirtyComponent
。
當(dāng)上一次更新機(jī)制執(zhí)行完畢建峭,以生命周期為例玻侥,所有組件,即最頂層組件 didmount
后會(huì)將批處理標(biāo)志設(shè)置為 false
亿蒸。這時(shí)將取出 dirtyComponent
中的組件以及 _pendingStateQueue
中的 state
進(jìn)行更新凑兰。這樣就可以確保組件不會(huì)被重新渲染多次。
當(dāng)我們?cè)趫?zhí)行 setState
后立即去獲取 state
边锁,這時(shí)是獲取不到更新后的 state
的姑食,因?yàn)樘幱?React
的批處理機(jī)制中, state
被暫存起來(lái)茅坛,待批處理機(jī)制完成之后音半,統(tǒng)一進(jìn)行更新。
所以贡蓖。setState
本身并不是異步的曹鸠,而是 React
的批處理機(jī)制給人一種異步的假象。
-
異步代碼和原生事件中
當(dāng)我們?cè)诋惒酱a中調(diào)用setState
時(shí)斥铺,根據(jù)JavaScript
的異步機(jī)制彻桃,會(huì)將異步代碼先暫存,等所有同步代碼執(zhí)行完畢后在執(zhí)行晾蜘,這時(shí)React
的批處理機(jī)制已經(jīng)走完,處理標(biāo)志設(shè)被設(shè)置為false
笙纤,這時(shí)再調(diào)用setState
即可立即執(zhí)行更新耗溜,拿到更新后的結(jié)果组力。
在原生事件中調(diào)用 setState
并不會(huì)出發(fā) React
的批處理機(jī)制省容,所以立即能拿到最新結(jié)果。
- 最佳實(shí)踐
setState
的第二個(gè)參數(shù)接收一個(gè)函數(shù)燎字,該函數(shù)會(huì)在 React
的批處理機(jī)制完成之后調(diào)用腥椒,所以你想在調(diào)用 setState
后立即獲取更新后的值,請(qǐng)?jiān)谠摶卣{(diào)函數(shù)中獲取候衍。
為什么有時(shí)連續(xù)多次setState只有一次生效笼蛛?
原因就是 React
會(huì)批處理機(jī)制中存儲(chǔ)的多個(gè) setState
進(jìn)行合并,來(lái)看下 React
源碼中的 _assign
函數(shù)蛉鹿,類似于 Object
的 assign
:
如果傳入的是對(duì)象滨砍,很明顯會(huì)被合并成一次,所以上面的代碼兩次打印的結(jié)果是相同的
- 最佳實(shí)踐
React
會(huì)對(duì)多次連續(xù)的 setState
進(jìn)行合并,如果你想立即使用上次 setState
后的結(jié)果進(jìn)行下一次 setState
惋戏,可以讓 setState
接收一個(gè)函數(shù)而不是一個(gè)對(duì)象领追。這個(gè)函數(shù)用上一個(gè) state
作為第一個(gè)參數(shù),將此次更新被應(yīng)用時(shí)的 props
做為第二個(gè)參數(shù)响逢。
4. React如何實(shí)現(xiàn)自己的事件機(jī)制绒窑?
React
事件并沒(méi)有綁定在真實(shí)的 Dom
節(jié)點(diǎn)上,而是通過(guò)事件代理舔亭,在最外層的 document
上對(duì)事件進(jìn)行統(tǒng)一分發(fā)些膨。
組件掛載、更新時(shí):
通過(guò)
lastProps
钦铺、nextProps
判斷是否新增订雾、刪除事件分別調(diào)用事件注冊(cè)、卸載方法矛洞。調(diào)用
EventPluginHub
的enqueuePutListener
進(jìn)行事件存儲(chǔ)獲取
document
對(duì)象葬燎。根據(jù)事件名稱(如
onClick
、onCaptureClick
)判斷是進(jìn)行冒泡還是捕獲缚甩。判斷是否存在
addEventListener
方法谱净,否則使用attachEvent
(兼容IE)。給
document
注冊(cè)原生事件回調(diào)為dispatchEvent
(統(tǒng)一的事件分發(fā)機(jī)制)擅威。
事件初始化:
EventPluginHub
負(fù)責(zé)管理React
合成事件的callback
壕探,它將callback
存儲(chǔ)在listenerBank
中,另外還存儲(chǔ)了負(fù)責(zé)合成事件的Plugin
郊丛。獲取綁定事件的元素的唯一標(biāo)識(shí)
key
李请。將
callback
根據(jù)事件類型,元素的唯一標(biāo)識(shí)key
存儲(chǔ)在listenerBank
中厉熟。listenerBank
的結(jié)構(gòu)是:listenerBank[registrationName][key]
导盅。
觸發(fā)事件時(shí):
觸發(fā)
document
注冊(cè)原生事件的回調(diào)dispatchEvent
獲取到觸發(fā)這個(gè)事件最深一級(jí)的元素
遍歷這個(gè)元素的所有父元素,依次對(duì)每一級(jí)元素進(jìn)行處理揍瑟。
構(gòu)造合成事件白翻。
將每一級(jí)的合成事件存儲(chǔ)在
eventQueue
事件隊(duì)列中。遍歷
eventQueue
绢片。通過(guò)
isPropagationStopped
判斷當(dāng)前事件是否執(zhí)行了阻止冒泡方法滤馍。如果阻止了冒泡,停止遍歷底循,否則通過(guò)
executeDispatch
執(zhí)行合成事件巢株。釋放處理完成的事件。
React
在自己的合成事件中重寫了 stopPropagation
方法熙涤,將 isPropagationStopped
設(shè)置為 true
阁苞,然后在遍歷每一級(jí)事件的過(guò)程中根據(jù)此遍歷判斷是否繼續(xù)執(zhí)行困檩。這就是 React
自己實(shí)現(xiàn)的冒泡機(jī)制。
5. 為何React事件要自己綁定this那槽?
在上面提到的事件處理流程中窗看, React
在 document
上進(jìn)行統(tǒng)一的事件分發(fā), dispatchEvent
通過(guò)循環(huán)調(diào)用所有層級(jí)的事件來(lái)模擬事件冒泡和捕獲倦炒。
在 React
源碼中显沈,當(dāng)具體到某一事件處理函數(shù)將要調(diào)用時(shí),將調(diào)用 invokeGuardedCallback
方法逢唤。
function invokeGuardedCallback(name, func, a) {
try {
func(a);
} catch (x) {
if (caughtError === null) {
caughtError = x;
}
}
}}
可見(jiàn)拉讯,事件處理函數(shù)是直接調(diào)用的,并沒(méi)有指定調(diào)用的組件鳖藕,所以不進(jìn)行手動(dòng)綁定的情況下直接獲取到的 this
是不準(zhǔn)確的魔慷,所以我們需要手動(dòng)將當(dāng)前組件綁定到 this
上。
6. 原生事件和React事件的區(qū)別著恩?
React
事件使用駝峰命名院尔,而不是全部小寫。通過(guò)
JSX
, 你傳遞一個(gè)函數(shù)作為事件處理程序喉誊,而不是一個(gè)字符串邀摆。在
React
中你不能通過(guò)返回false
來(lái)阻止默認(rèn)行為。必須明確調(diào)用preventDefault
伍茄。
7. React的合成事件是什么栋盹?
React
根據(jù) W3C
規(guī)范定義了每個(gè)事件處理函數(shù)的參數(shù),即合成事件敷矫。
事件處理程序?qū)鬟f SyntheticEvent
的實(shí)例例获,這是一個(gè)跨瀏覽器原生事件包裝器。它具有與瀏覽器原生事件相同的接口曹仗,包括 stopPropagation()
和 preventDefault()
榨汤,在所有瀏覽器中他們工作方式都相同。
React
合成的 SyntheticEvent
采用了事件池怎茫,這樣做可以大大節(jié)省內(nèi)存收壕,而不會(huì)頻繁的創(chuàng)建和銷毀事件對(duì)象。
另外遭居,不管在什么瀏覽器環(huán)境下啼器,瀏覽器會(huì)將該事件類型統(tǒng)一創(chuàng)建為合成事件旬渠,從而達(dá)到了瀏覽器兼容的目的俱萍。
8. React和原生事件的執(zhí)行順序是什么?可以混用嗎告丢?
React
的所有事件都通過(guò) document
進(jìn)行統(tǒng)一分發(fā)枪蘑。當(dāng)真實(shí) Dom
觸發(fā)事件后冒泡到 document
后才會(huì)對(duì) React
事件進(jìn)行處理损谦。
所以原生的事件會(huì)先執(zhí)行,然后執(zhí)行 React
合成事件岳颇,最后執(zhí)行真正在 document
上掛載的事件
React
事件和原生事件最好不要混用照捡。原生事件中如果執(zhí)行了 stopPropagation
方法,則會(huì)導(dǎo)致其他 React
事件失效话侧。因?yàn)樗性氐氖录o(wú)法冒泡到 document
上栗精,導(dǎo)致所有的 React
事件都將無(wú)法被觸發(fā)。瞻鹏。
9. 虛擬Dom是什么悲立?
在原生的 JavaScript
程序中,我們直接對(duì) DOM
進(jìn)行創(chuàng)建和更改新博,而 DOM
元素通過(guò)我們監(jiān)聽(tīng)的事件和我們的應(yīng)用程序進(jìn)行通訊薪夕。
而 React
會(huì)先將你的代碼轉(zhuǎn)換成一個(gè) JavaScript
對(duì)象,然后這個(gè) JavaScript
對(duì)象再轉(zhuǎn)換成真實(shí) DOM
赫悄。這個(gè) JavaScript
對(duì)象就是所謂的虛擬 DOM
原献。
當(dāng)我們需要?jiǎng)?chuàng)建或更新元素時(shí), React
首先會(huì)讓這個(gè) VitrualDom
對(duì)象進(jìn)行創(chuàng)建和更改埂淮,然后再將 VitrualDom
對(duì)象渲染成真實(shí)DOM姑隅。
當(dāng)我們需要對(duì) DOM
進(jìn)行事件監(jiān)聽(tīng)時(shí),首先對(duì) VitrualDom
進(jìn)行事件監(jiān)聽(tīng)倔撞, VitrualDom
會(huì)代理原生的 DOM
事件從而做出響應(yīng)粤策。
10. 虛擬Dom比普通Dom更快嗎?
很多文章說(shuō) VitrualDom
可以提升性能误窖,這一說(shuō)法實(shí)際上是很片面的叮盘。
直接操作 DOM
是非常耗費(fèi)性能的,這一點(diǎn)毋庸置疑霹俺。但是 React
使用 VitrualDom
也是無(wú)法避免操作 DOM
的柔吼。
如果是首次渲染, VitrualDom
不具有任何優(yōu)勢(shì)丙唧,甚至它要進(jìn)行更多的計(jì)算愈魏,消耗更多的內(nèi)存。
VitrualDom
的優(yōu)勢(shì)在于 React
的 Diff
算法和批處理策略想际, React
在頁(yè)面更新之前培漏,提前計(jì)算好了如何進(jìn)行更新和渲染 DOM
。實(shí)際上胡本,這個(gè)計(jì)算過(guò)程我們?cè)谥苯硬僮?DOM
時(shí)牌柄,也是可以自己判斷和實(shí)現(xiàn)的,但是一定會(huì)耗費(fèi)非常多的精力和時(shí)間侧甫,而且往往我們自己做的是不如 React
好的珊佣。所以蹋宦,在這個(gè)過(guò)程中 React
幫助我們"提升了性能"。
所以咒锻,我更傾向于說(shuō)冷冗, VitrualDom
幫助我們提高了開發(fā)效率,在重復(fù)渲染時(shí)它幫助我們計(jì)算如何更高效的更新惑艇,而不是它比 DOM
操作更快蒿辙。
11. 虛擬Dom中的$$typeof屬性的作用是什么?
ReactElement
中有一個(gè) $$typeof
屬性滨巴,它被賦值為 REACT_ELEMENT_TYPE
:
var REACT_ELEMENT_TYPE =`(typeof Symbol === 'function' && Symbol.for && Symbol.for('react.element')) || 0xeac7`;
可見(jiàn)须板, $$typeof
是一個(gè) Symbol
類型的變量,這個(gè)變量可以防止 XSS
兢卵。
如果你的服務(wù)器有一個(gè)漏洞习瑰,允許用戶存儲(chǔ)任意 JSON
對(duì)象, 而客戶端代碼需要一個(gè)字符串秽荤,這可能會(huì)成為一個(gè)問(wèn)題:
// JSON
let expectedTextButGotJSON = {
type: 'div',
props: {
dangerouslySetInnerHTML: {
__html: '/* put your exploit here */'
},
},
};
let message = { text: expectedTextButGotJSON };
<p>{message.text}</p>
JSON
中不能存儲(chǔ) Symbol
類型的變量甜奄。
ReactElement.isValidElement
函數(shù)用來(lái)判斷一個(gè) React
組件是否是有效的∏钥睿可見(jiàn) React
渲染時(shí)會(huì)把沒(méi)有 $$typeof
標(biāo)識(shí)课兄,以及規(guī)則校驗(yàn)不通過(guò)的組件過(guò)濾掉。
當(dāng)你的環(huán)境不支持 Symbol
時(shí)晨继, $$typeof
被賦值為 0xeac7
烟阐,至于為什么, React
開發(fā)者給出了答案:
0xeac7
看起來(lái)有點(diǎn)像React
紊扬。
12. React組件的渲染流程是什么蜒茄?
使用
React.createElement
或JSX
編寫React
組件,實(shí)際上所有的JSX
代碼最后都會(huì)轉(zhuǎn)換成React.createElement(...)
餐屎,Babel
幫助我們完成了這個(gè)轉(zhuǎn)換的過(guò)程檀葛。createElement
函數(shù)對(duì)key
和ref
等特殊的props
進(jìn)行處理,并獲取defaultProps
對(duì)默認(rèn)props
進(jìn)行賦值腹缩,并且對(duì)傳入的孩子節(jié)點(diǎn)進(jìn)行處理屿聋,最終構(gòu)造成一個(gè)ReactElement
對(duì)象(所謂的虛擬DOM
)。ReactDOM.render
將生成好的虛擬DOM
渲染到指定容器上藏鹊,其中采用了批處理润讥、事務(wù)等機(jī)制并且對(duì)特定瀏覽器進(jìn)行了性能優(yōu)化,最終轉(zhuǎn)換為真實(shí)DOM
盘寡。
13. 為什么代碼中一定要引入React楚殿?
JSX
只是為 React.createElement(component,props,...children)
方法提供的語(yǔ)法糖。
所有的 JSX
代碼最后都會(huì)轉(zhuǎn)換成 React.createElement(...)
宴抚, Babel
幫助我們完成了這個(gè)轉(zhuǎn)換的過(guò)程勒魔。
所以使用了 JSX
的代碼都必須引入 React
甫煞。
14. 為什么React組件首字母必須大寫菇曲?
babel
在編譯時(shí)會(huì)判斷 JSX
中組件的首字母冠绢,當(dāng)首字母為小寫時(shí),其被認(rèn)定為原生 DOM
標(biāo)簽常潮, createElement
的第一個(gè)變量被編譯為字符串弟胀;當(dāng)首字母為大寫時(shí),其被認(rèn)定為自定義組件喊式, createElement
的第一個(gè)變量被編譯為對(duì)象孵户;
15. React在渲染真實(shí)Dom時(shí)做了哪些性能優(yōu)化?
在 IE(8-11)
和 Edge
瀏覽器中岔留,一個(gè)一個(gè)插入無(wú)子孫的節(jié)點(diǎn)夏哭,效率要遠(yuǎn)高于插入一整個(gè)序列化完整的節(jié)點(diǎn)樹。
React
通過(guò) lazyTree
献联,在 IE(8-11)
和 Edge
中進(jìn)行單個(gè)節(jié)點(diǎn)依次渲染節(jié)點(diǎn)竖配,而在其他瀏覽器中則首先將整個(gè)大的 DOM
結(jié)構(gòu)構(gòu)建好,然后再整體插入容器里逆。
并且进胯,在單獨(dú)渲染節(jié)點(diǎn)時(shí), React
還考慮了 fragment
等特殊節(jié)點(diǎn)原押,這些節(jié)點(diǎn)則不會(huì)一個(gè)一個(gè)插入渲染胁镐。
16. 什么是高階組件?如何實(shí)現(xiàn)诸衔?
高階組件可以看作 React
對(duì)裝飾模式的一種實(shí)現(xiàn)盯漂,高階組件就是一個(gè)函數(shù),且該函數(shù)接受一個(gè)組件作為參數(shù)笨农,并返回一個(gè)新的組件宠能。
高階組件( HOC
)是 React
中的高級(jí)技術(shù),用來(lái)重用組件邏輯磁餐。但高階組件本身并不是 ReactAPI
违崇。它只是一種模式,這種模式是由 React
自身的組合性質(zhì)必然產(chǎn)生的诊霹。
function visible(WrappedComponent) {
return class extends Component {
render() {
const { visible, ...props } = this.props;
if (visible === false) return null;
return <WrappedComponent {...props} />;
}
}
}
上面的代碼就是一個(gè) HOC
的簡(jiǎn)單應(yīng)用羞延,函數(shù)接收一個(gè)組件作為參數(shù),并返回一個(gè)新組件脾还,新組建可以接收一個(gè) visible props
伴箩,根據(jù) visible
的值來(lái)判斷是否渲染Visible。
我們可以通過(guò)以下兩種方式實(shí)現(xiàn)高階組件:
17. 屬性代理
函數(shù)返回一個(gè)我們自己定義的組件鄙漏,然后在 render
中返回要包裹的組件嗤谚,這樣我們就可以代理所有傳入的 props
棺蛛,并且決定如何渲染,實(shí)際上 巩步,這種方式生成的高階組件就是原組件的父組件旁赊,上面的函數(shù) visible
就是一個(gè) HOC
屬性代理的實(shí)現(xiàn)方式。
function proxyHOC(WrappedComponent) {
return class extends Component {
render() {
return <WrappedComponent {...this.props} />;
}
}
}
對(duì)比原生組件增強(qiáng)的項(xiàng):
可操作所有傳入的
props
可操作組件的生命周期
可操作組件的
static
方法獲取
refs
18. 反向繼承
返回一個(gè)組件椅野,繼承原組件终畅,在 render
中調(diào)用原組件的 render
。由于繼承了原組件竟闪,能通過(guò)this訪問(wèn)到原組件的 生命周期离福、props、state炼蛤、render
等妖爷,相比屬性代理它能操作更多的屬性。
function inheritHOC(WrappedComponent) {
return class extends WrappedComponent {
render() {
return super.render();
}
}
}
對(duì)比原生組件增強(qiáng)的項(xiàng):
可操作所有傳入的
props
可操作組件的生命周期
可操作組件的
static
方法獲取
refs
可操作
state
可以渲染劫持
19. HOC在業(yè)務(wù)場(chǎng)景中有哪些實(shí)際應(yīng)用場(chǎng)景理朋?
HOC
可以實(shí)現(xiàn)的功能:
組合渲染
條件渲染
操作
props
獲取
refs
狀態(tài)管理
操作
state
渲染劫持
HOC
在業(yè)務(wù)中的實(shí)際應(yīng)用場(chǎng)景:
日志打點(diǎn)
權(quán)限控制
雙向綁定
表單校驗(yàn)
20. 高階組件(HOC)和Mixin的異同點(diǎn)是什么絮识?
Mixin
和 HOC
都可以用來(lái)解決 React
的代碼復(fù)用問(wèn)題。
Mixin
可能會(huì)相互依賴暗挑,相互耦合笋除,不利于代碼維護(hù)不同的
Mixin
中的方法可能會(huì)相互沖突Mixin
非常多時(shí),組件是可以感知到的炸裆,甚至還要為其做相關(guān)處理垃它,這樣會(huì)給代碼造成滾雪球式的復(fù)雜性
而 HOC
的出現(xiàn)可以解決這些問(wèn)題:
高階組件就是一個(gè)沒(méi)有副作用的純函數(shù),各個(gè)高階組件不會(huì)互相依賴耦合
高階組件也有可能造成沖突烹看,但我們可以在遵守約定的情況下避免這些行為
高階組件并不關(guān)心數(shù)據(jù)使用的方式和原因国拇,而被包裹的組件也不關(guān)心數(shù)據(jù)來(lái)自何處。高階組件的增加不會(huì)為原組件增加負(fù)擔(dān)
21. Hook有哪些優(yōu)勢(shì)惯殊?
- 減少狀態(tài)邏輯復(fù)用的風(fēng)險(xiǎn)
Hook
和 Mixin
在用法上有一定的相似之處酱吝,但是 Mixin
引入的邏輯和狀態(tài)是可以相互覆蓋的,而多個(gè) Hook
之間互不影響土思,這讓我們不需要在把一部分精力放在防止避免邏輯復(fù)用的沖突上务热。在不遵守約定的情況下使用 HOC
也有可能帶來(lái)一定沖突,比如 props
覆蓋等等己儒,使用 Hook
則可以避免這些問(wèn)題崎岂。
- 避免地獄式嵌套
大量使用 HOC
的情況下讓我們的代碼變得嵌套層級(jí)非常深,使用 HOC
闪湾,我們可以實(shí)現(xiàn)扁平式的狀態(tài)邏輯復(fù)用冲甘,而避免了大量的組件嵌套。
- 讓組件更容易理解
在使用 class
組件構(gòu)建我們的程序時(shí),他們各自擁有自己的狀態(tài)江醇,業(yè)務(wù)邏輯的復(fù)雜使這些組件變得越來(lái)越龐大濒憋,各個(gè)生命周期中會(huì)調(diào)用越來(lái)越多的邏輯,越來(lái)越難以維護(hù)陶夜。使用 Hook
凛驮,可以讓你更大限度的將公用邏輯抽離,將一個(gè)組件分割成更小的函數(shù)律适,而不是強(qiáng)制基于生命周期方法進(jìn)行分割辐烂。
- 使用函數(shù)代替class
相比函數(shù)遏插,編寫一個(gè) class
可能需要掌握更多的知識(shí)捂贿,需要注意的點(diǎn)也越多,比如 this
指向胳嘲、綁定事件等等厂僧。另外,計(jì)算機(jī)理解一個(gè) class
比理解一個(gè)函數(shù)更快了牛。Hooks
讓你可以在 classes
之外使用更多 React
的新特性颜屠。