1. withRouter
組件導(dǎo)出時(shí)用它來(lái)包裹僻造,這樣才能在組件內(nèi)使用 this.props.history/location/match
export default withRouter(adminSubjectType);
https://blog.csdn.net/weixin_43271750/article/details/86299567
一缘挽、Hook:JavaScript 函數(shù)
1.基本使用規(guī)則
(1)只能在 函數(shù)最外層 調(diào)用 Hook。不要在 循環(huán)律想、條件判斷 或者 子函數(shù) 中調(diào)用。如果我們想要有條件地執(zhí)行一個(gè) effect,可以將判斷放到 Hook 的內(nèi)部:
useEffect(function persistForm() {
// ?? 將條件判斷放置在 effect 中
if (name !== '') {
localStorage.setItem('formData', name);
}
});
(2)只能在 React 的 函數(shù)組件中調(diào)用 Hook舷嗡。不要在其他 JavaScript 函數(shù)中調(diào)用扫外,Hook 在 class 內(nèi)部是 不起作用的(另外莉钙,自定義Hook中也可以調(diào)用Hook)
(3)單個(gè)組件內(nèi),無(wú)論是State Hook或者Effect Hook筛谚,都可以 多次被調(diào)用磁玉。
2.State Hook
使用:
(1)引入 useState Hook。
(2)通過(guò) useState() 聲明變量驾讲、聲明修改變量的方法蚊伞、為變量初始化值。
(3)調(diào)用 修改變量的方法 修改狀態(tài)值吮铭,注意 函數(shù)組件內(nèi)沒(méi)有this时迫。
寫(xiě)法一:直接將最新值作為參數(shù)傳入 setState(最新值)
寫(xiě)法二:函數(shù)作為參數(shù),接收舊值谓晌,手動(dòng)返回新值 setState((oldValue)=>newValue)
1: import React, { useState } from 'react';
2:
3: function Example() {
4: const [count, setCount] = useState(100);
5:
6: return (
7: <div>
8: <p>You clicked {count} times</p>
9: <button onClick={() => setCount(count + 1)}>
10: Click me
11: </button>
12: </div>
13: );
14: }
說(shuō)明:
(1)useState()函數(shù)接收的參數(shù)掠拳,就是 變量的初始值,可以是數(shù)字纸肉、字符串溺欧、數(shù)組、對(duì)象毁靶、等數(shù)據(jù)類(lèi)型胧奔。
(2)useState()函數(shù)的返回值是一個(gè)數(shù)組,分別代表 當(dāng)前 state 以及 更新 state 的函數(shù)预吆。
3. Effect Hook
(1)引入 useEffec tHook龙填。
(2)調(diào)用時(shí),第一個(gè)參數(shù)是一個(gè) 函數(shù),第二個(gè)參數(shù)是一個(gè) 數(shù)組岩遗。
useEffect(()=>{ }扇商,[])
① 第一個(gè)參數(shù)相當(dāng)于 生命周期鉤子。
② 第二個(gè)參數(shù)相當(dāng)于 監(jiān)聽(tīng)某些state數(shù)據(jù)的變化宿礁。
③ 如果不傳第二個(gè)數(shù)組案铺,則第一個(gè)函數(shù)相當(dāng)于componentDidMount、componentDidUpdate梆靖,在 頁(yè)面首次渲染 后和 每次更新 后都會(huì)執(zhí)行控汉。
④ 如果傳了第二個(gè)數(shù)組,則第一個(gè)函數(shù)會(huì)在 頁(yè)面首次渲染返吻、被監(jiān)聽(tīng)的數(shù)據(jù)更新 時(shí)被調(diào)用姑子。
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// 無(wú)需清除的副作用:DOM首次渲染完成 或 更新后,設(shè)置標(biāo)題
useEffect(() => {
document.title = `你點(diǎn)擊了 ${count} 次`;
});
// 無(wú)需清除的副作用:只在DOM首次渲染完成時(shí)執(zhí)行
useEffect(()=>{
console.log('DOM首次渲染完成测僵!')
},[])
return (
<div>
<button onClick={() => setCount(count + 1)}>點(diǎn)我加1</button>
</div>
);
}
(3)如果想要 清除副作用街佑,在useEffect()的執(zhí)行器函數(shù)中,返回一個(gè)函數(shù)捍靠,被返回的函數(shù)就相當(dāng)于 componentWillUnmount沐旨,可以進(jìn)行清除定時(shí)器等清除操作。
handler=()=>{
console.log('瀏覽器大小發(fā)生了變化')
}
useEffect(() => {
window.addEventListener('resize'榨婆,handler)
return () => {
window.removeEventListener('resize'磁携,handler)
};
});
另外:將 useEffect() 放在 組件內(nèi)部,讓我們可以在 effect 中直接訪問(wèn) state 變量(或其他 props)纲辽。
4.Ref Hook
類(lèi)似于類(lèi)組件中 createRef() 的使用:
(1)引入 useRef
(2)調(diào)用 useRef() 函數(shù)
const myRef = useRef()
(3)給組件綁定ref
<input ref={myRef} />
注意:不能給函數(shù)組件綁定Ref
① 如果 子組件 是 函數(shù)組件颜武,父組件想要給子組件綁定Ref來(lái)獲取子組件數(shù)據(jù)的話(huà),需要用到 forwdRef拖吼。
② 先在父組件內(nèi)定義Ref變量,并給子組件 綁定Ref这吻。
③ 子組件內(nèi)吊档,子組件函數(shù)要 用forwdRef()函數(shù)包裹,函數(shù)第二個(gè)參數(shù)可以拿到父組件Ref唾糯。
④ 通過(guò)react 的 useImperativeHandle() 函數(shù)怠硼,可以暴露數(shù)據(jù)、方法給父組件移怯。
import React, {useRef} from 'react';
const Father= (props) => {
const SonRef= useRef(null)
return <TableInfo title="資產(chǎn)所有人" ref={SonRef}></TableInfo>
}
import React, {useImperativeHandle, useState, forwardRef} from 'react';
const TableInfo = (props, parentRef)=>{
const [data, setData] = useState([1,2,3])
// 設(shè)置暴露給父組件的數(shù)據(jù)
useImperativeHandle(parentRef, () => ({data}));
}
export default forwardRef(TableInfo)
⑤ 用useRef定義的變量可以跨頁(yè)生效香璃,useState變量只在當(dāng)前頁(yè)面生效:const aRef = useRef=(0) ;aRef.current = 80
5.自定義Hook
二舟误、useCallback
1.使用useEffect()請(qǐng)求到接口數(shù)據(jù)后葡秒,會(huì)對(duì)state數(shù)據(jù)進(jìn)行賦值。
2.如果這個(gè)方法 對(duì)自身具有依賴(lài)(組件通訊),或者對(duì)useState中的數(shù)據(jù)有依賴(lài):方法執(zhí)行時(shí),內(nèi)部的賦值操作會(huì)引起頁(yè)面重新渲染——重新渲染會(huì)生成新的方法——而方法本身對(duì)自己有依賴(lài)眯牧,所以方法更新時(shí)方法又會(huì)重新執(zhí)行蹋岩。
參考:http://www.reibang.com/p/be8fb469d507
import React, {useEffect, useState ,useCallback} from 'react';
const getInfo = useCallback((props)=>{
StructureApi.getDetailInfo(id).then(res => {
setBasicInfo(res.data.data)
})
},[props.match])
useEffect(() => {
getInfo(props);
}, [getInfo]);
三、Fragment
無(wú)論是類(lèi)組件学少、函數(shù)組件中剪个,HtML結(jié)構(gòu)最外層的<div></div>標(biāo)簽,可以替換為:
<Fragment> </Fragment> 或是 <> </>
① Fragment可以接收一個(gè) key屬性 用于遍歷時(shí)的 唯一標(biāo)識(shí)版确。
② 空標(biāo)簽不能接收任何屬性扣囊。
四、錯(cuò)誤邊界
1. 什么是錯(cuò)誤邊界
就是在 親爹 父組件內(nèi)绒疗, 監(jiān)測(cè)如暖、捕獲、處理 可能出現(xiàn)錯(cuò)誤的子組件忌堂,并 渲染備用組件盒至。
2. getDerivedStateFromError( )
(1)在 親爹 父組件內(nèi)添加 生命周期函數(shù) getDerivedStateFromError( )。
(2)參數(shù) 是捕獲到的 子組件 的 錯(cuò)誤對(duì)象士修。
(3)返回值是一個(gè) 對(duì)象枷遂,這個(gè)對(duì)象可以 修改父組件的state數(shù)據(jù)。
(4)父組件 提前聲明一個(gè)state數(shù)據(jù)棋嘲,用于判斷子組件是否出錯(cuò)酒唉,并渲染子組件或備用組件。
import React from 'react'
import Kid from './child.jsx'
class Parent extends React.Component {
// 1.父組件聲明一個(gè)變量沸移,用來(lái)控制渲染 【子組件】 或 【備用組件】
state = { hasError: false }
// 2. 當(dāng)子組件發(fā)生錯(cuò)誤時(shí)痪伦,獲取錯(cuò)誤信息,并修改父組件的state數(shù)據(jù)雹锣。
static getDerivedStateFromError (error) {
return {hasError: error}
}
render () {
return (
<div>
{/* 3.根據(jù)hasError判斷是否渲染子組件*/}
{this.state.hasError ? '子組件出現(xiàn)了錯(cuò)誤网沾! ': <Kid></Kid>}
</div>
)
}
}
// 導(dǎo)出組件
export default Hello
注意:
(1)只能捕獲后代組件 生命周期 產(chǎn)生的錯(cuò)誤,主要針對(duì)的是 render( )蕊爵。
(2)不能捕獲父組件本身錯(cuò)誤辉哥、其他組件在合成事件或定時(shí)器中產(chǎn)生的錯(cuò)誤。
3. componentDidCatch( )
(1)在 父組件 內(nèi)添加這個(gè) 生命周期函數(shù)攒射。
(2)接收兩個(gè)參數(shù)醋旦,用于統(tǒng)計(jì)子組件出現(xiàn)的錯(cuò)誤次數(shù)。