React及Nextjs知識點小結
函數式組件和類組件區別是什么
1、函數式組件是用於創建無狀態的組件,組件不會被實例化,無法訪問this中的對象,無法訪問生命周期方法,是無副作用的,相比於類組件函數式組件代碼可讀性更好,減少了大量的冗余代碼,可以很方便的創建一個組件
2、類組件是用於創建有狀態的組件,該組件會被實例化,可以訪問組件的生命周期方法
Component和PureCompoent區別是什么
1、PureCompoent是一個更具性能的Component的版本
除了為你提供了一個具有淺比較的shouldComponentUpdate方法,PureComponent和Component基本上完全相2、同。當props或者state改變時,PureComponent將對props和state進行淺比較。
3、另外,Component不會比較當前和下個狀態的props和state。因此,每當shouldComponentUpdate被調用時,組件默認的會重新渲染。
屬性Props和States應該在何時使用
組件私有數據時用state 外部數據傳入則用props
簡單說明React Component的生命周期
react組件的生命周期有四個階段:初始化、創建階段、運行階段和銷毀階段
1、初始化:
construct,初始化state,並且把props轉化為state
2、創建階段:
componentWillMount,相當於 Vue 中的 created,組件將要被掛載,此時還沒有開始渲染虛擬 DOM
componentDidMount,相對於 Vue 中的mounted,組件完成掛載,此時,組件已經顯示到頁面上了,通常我們會在這里請求ajax數據,或是操作dom改變樣式
3、運行階段
componentWillReceiveProps(注:未來17版本中將被棄用):組件接收到一個新的props時被調用,但也有可能props沒有改變的時候也觸發,比如父組件更新導致的觸發,有時候可能需要比較props是否發生了改變,這個方法在第一次渲染時不會被調用。
shouldComponentUpdate:用於判斷組件是否需要被更新,一般在這里做一些性能優化,減少不必要的渲染
componentWillUpdate(注:未來17版本中將被棄用),組件更新之前(componentshouldupdate返回true)時調用
componentDidUpdate,組件更新完成之后調用,此時頁面又被重新渲染了, state、虛擬DOM和頁面已經保持同步
4、銷毀階段
componentWillUnmount,組件卸載的時候觸發,我們可以在這里做一些清除定時器的操作
新增加的鈎子函數
1、getDerivedStateFromProps(nextProps,prevState)
新的靜態getDerivedStateFromProps生命周期在組件實例化以及接收新props(只要父組件重新渲染,那么這個props不論值是否一樣都是一個新的props)后調用。它可以返回一個對象來更新state,或者返回null來表示新的props不需要任何state更新。
2、getSnapshotBeforeUpdate()
新的getSnapshotBeforeUpdate生命周期在更新之前被調用(例如,在DOM被更新之前)。此生命周期的返回值將作為第三個參數傳遞給componentDidUpdate。 (這個生命周期不是經常需要的,但可以用於在恢復期間手動保存滾動位置的情況。)
HOC組件是什么,舉一個合適使用HOC的例子
高階組件就是一個函數,且該函數接受一個組件作為參數,並返回一個新的組件,是一個沒有副作用的純函數。
舉個例子,如頁面權限控制
// HOC.js
function withAdminAuth(WrappedComponent) {
return class extends React.Component {
state = {
isAdmin: false,
}
async componentWillMount() {
const currentRole = await getCurrentUserRole();
this.setState({
isAdmin: currentRole === 'Admin',
});
}
render() {
if (this.state.isAdmin) {
return <WrappedComponent {...this.props} />;
} else {
return (<div>您沒有權限查看該頁面,請聯系管理員!</div>);
}
}
};
}
頁面a
// pages/page-a.js
class PageA extends React.Component {
constructor(props) {
super(props);
// something here...
}
componentWillMount() {
// fetching data
}
render() {
// render page with data
}
}
export default withAdminAuth(PageA);
什么事RenderProps?舉一個合適使用RenderProps的例子
The Render Props是一種在不重復代碼的情況下共享組件間功能的方法,Render Props模式的出現主要是為了解決HOC所出現的問題
- 不用擔心props命名問題,在render函數中只取需要的state
- 不會產生無用的組件加深層級
- render props模式的構建都是動態的,所有的改變都在render中觸發,可以更好的利用組件內的生命周期。
使用場景:
Render Props對於只讀操作非常適用,如跟蹤屏幕上的滾動位置或鼠標位置
怎樣可以知道Nextjs現在的代碼是在前端還是后端運行
服務端和客戶端本質區別是誰來完成html內容的拼接,如是在服務器端完成的,然后返回給客戶端則是服務器端渲染,如果是客戶端來拼接頁面內容數據,則是客戶端渲染。
判斷當前頁面是客戶端還是服務器端渲染有三種方式:
a、可以通過查看Network請求來區分,如果是客戶端請求,Respone返回的是Json數據,否則返回的是html格式的內容數據
b、查看源代碼,如果頁面中展示的數據在源代碼中可以看到說明是服務器端渲染,否則是客戶端渲染
c、通過 isServer 變量可以判斷當前環境是服務端還是客戶端
static async getInitialProps(ctx) {
const isServer = ctx.isServer
}
簡單說明Nextjs中頁面的生命周期
Next.js為我們提供了一個區別於React的新生命周期——getIntialProps(),這個生命周期是脫離於React的正常生命周期的,不過我們依然可以在組件里正常使用react組件的各種生命周期函數。
getInitialProps ,它用於獲取並處理組件的屬性,返回組件的默認屬性。我們可以在該方法中請求數據,獲取頁面需要的數據並渲染返回給前端頁面。
當頁面初始化加載時,getInitialProps只會加載在服務端。只有當路由跳轉(Link組件跳轉或 API 方法跳轉)時,客戶端才會執行getInitialProps。
注意:getInitialProps將不能使用在子組件中。只能使用在pages頁面中。
static async getInitialProps({ req, query, store }) {
store.dispatch(getPromoItemRequest())
store.dispatch(getHomePageDataRequest())
return {}
}
請說明Router,Link以及location.href在Nextjs中的區別
Router是一個路由對象,提供了route、pathname、query、push、replace等常用的API
<span onClick={() => Router.push('/about')}>here</span>
Link是一個組件,其實現原理是基於Router
組件默認將新 url 推入路由棧中,可以使用replace屬性來防止添加新輸入
<Link href="/about" replace>
<a>here</a>
</Link>
location.href是Js提供的原生跳轉方式,相較於 location.href,Router和Link更加的強大和方便
請說明Link中,href和as分別代表什么
href鏈接跳轉的真實路徑
as為展現在瀏覽器上的實際路徑,是為了裝飾 URL 作用
什么時候才需要使用_app.js及什么東西需要放進_app.js
1、通過重寫_app.js文件,我們可以對App組件進行重構,在App組件中加入一些項目中不變的內容,比如頁面的布局
2、設置全局公共樣式css及狀態
3、使用componentDidCatch自定義處理錯誤
Nextjs中的production ENV(NODE_ENV=production)有什么特別
什么事單元測試及其准則是什么
單元測試(unittesting),是指對_軟件_中的最小可_測試單元_進行檢查和驗證
單元測試准則:
- 保持單元測試小巧, 快速
- 單元測試應該是全自動/非交互式的
- 讓單元測試很容易跑起來
- 對測試進行評估
- 立即修正失敗的測試
- 把測試維持在單元級別
- 由簡入繁
- 保持測試的獨立性
- Keep tests close to the class being tested
- 合理的命名測試用例
- 只測試公有接口
- 看成是黑盒
- 看成是白盒
- 芝麻函數也要測試
- 先關注執行覆蓋率
- 覆蓋邊界值
- 提供一個隨機值生成器
- 每個特性只測一次
- 使用顯式斷言
- 提供反向測試
- 代碼設計時謹記測試
- 不要訪問預定的外部資源
- 權衡測試成本
- 合理安排測試優先次序
- 為測試失敗做好准備
- 寫測試用例重現 bug
- 了解局限
如何提高單元測試的覆蓋率
提升代碼質量,高度的單元測試覆蓋率是最有效的手段之一
使用優秀的開源單元測試框架,其覆蓋率往往很高
高覆蓋體現在測試用例覆蓋public方法、函數中的if-else等邏輯、參數檢查、內部定義等。