2020前端面試真題( React )
JS部分
HTML + CSS
React
Vue
ES6
webpack,node.js,Git等
1.Redux遵循的三個原則是什麼?
單一資料來源
:整個應用的狀態儲存在單個 store 中的物件/狀態樹裡。單一狀態樹可以更容易地跟蹤隨時間的變化,並除錯或檢查應用程式。狀態是隻讀的
:改變狀態的唯一方法是去觸發一個動作。動作是描述變化的普通 JS 物件。就像 state 是資料的最小表示一樣,該操作是對資料更改的最小表示。使用純函式進行更改
:為了指定狀態樹如何通過操作進行轉換,需要用純函式。純函式是那些返回值僅取決於其引數值的函式。
2.redux工作流程
首先,UI元件發出 Action。然後,Store 自動呼叫 Reducer,並且傳入兩個引數:當前 State 和收到的 Action。 Reducer 會返回新的 State 。State 一旦有變化,Store 就會呼叫監聽函式。使用者可以通過store.getState()得到當前狀態。
//虛擬碼,僅供參考
() => store.dispatch({ type: 'CHANGE_VISIBLE' ,payload : text}) //發出Action
//reducer接受並處理資料
const reducer = (state = {
visible : false,
attritube : [],
}, action) => {
switch (action.type) {
case 'CHANGE_VISIBLE':
return { ...state, visible: !state.visible , attritube : action.payload }
default:
return state
}
}
//react類元件通過裝飾器獲取state資料
@connect(state => ({ visible: state.visible , attritube : state.attritube}), dispatch => ({}))
//函式式元件
export default connect((state => ({visible: state.visible , attritube : state.attritube})))('組價名')
3.React 中 key 的作用是什麼?
Keys 是 React 用於追蹤哪些列表中元素被修改、被新增或者被移除的輔助標識。
在開發過程中,我們需要保證某個元素的 key 在其同級元素中具有唯一性。在 React Diff 演算法中 React 會藉助元素的 Key 值來判斷該元素是新近建立的還是被移動而來的元素,從而減少不必要的元素重渲染。此外,React 還需要藉助 Key 值來判斷元素與本地狀態的關聯關係。
React中key的使用
4.React生命週期
- 常用的React生命週期方法 :
constructor()
: 如果不初始化 state 或不進行方法繫結,則不需要為 React 元件實現建構函式。
建構函式僅用於以下兩種情況:1. 通過給 this.state 賦值物件來初始化內部 state。2.為事件處理函式繫結例項
constructor(props) {
super(props);
// 不要在這裡呼叫 this.setState()
this.state = { counter: 0 };
this.handleClick = this.handleClick.bind(this);
}
-
Render()
: render() 方法是 class 元件中唯一必須實現的方法。
render() 函式應該為純函式,這意味著在不修改元件 state 的情況下,每次呼叫時都返回相同的結果,並且它不會直接與瀏覽器互動。 -
componentDidMount()
: 會在元件掛載後(插入 DOM 樹中)立即呼叫。如需通過網路請求獲取資料,此處是例項化請求的好地方。可以在 componentDidMount() 裡直接呼叫 setState()。 -
componentDidUpdate()
: componentDidUpdate(prevProps, prevState, snapshot)會在更新後會被立即呼叫。首次渲染不會執行此方法 -
componentWillUnmount()
: 會在元件解除安裝及銷燬之前直接呼叫。在此方法中執行必要的清理操作,例如,清除 timer,取消網路請求或清除在 componentDidMount() 中建立的訂閱等。componentWillUnmount() 中不應呼叫 setState(),因為該元件將永遠不會重新渲染。元件例項解除安裝後,將永遠不會再掛載它。
5.vue react 怎麼檢測資料變化的
React
- 16年之前可以使用componentWillReveiveProps來監聽props的變換。16年之後在最新版本的React中可以使用新出的getDerivedStateFromProps進行props的監聽,getDerivedStateFromProps可以返回null或者一個物件,如果是物件,則會更新state
- getDerivedStateFromProps的觸發條件 : 只要呼叫setState就會觸發getDerivedStateFromProps,並且props的值相同,也會觸發getDerivedStateFromProps(16.3版本之後)
- 狀態變化只能通過setState,呼叫setState就會更新狀態重新渲染dom
Vue
- vue監聽變數變化依靠的是watch
6.React中怎麼讓setState同步更新?
- 回撥 : setState函式的第二個引數允許傳入回撥函式,在狀態更新完畢後進行呼叫,例如下面的這個例子
this.setState({
data: '666'
}, () => {
console.log('載入完成')
});
- promise : 利用promise的特性,可以使用promise封裝一個函式去一勞永逸的解決這個問題
setStateAsync(state) {
return new Promise((resolve) => {
this.setState(state, resolve)
});
}
- async+await : 相當於promise的優雅版,我們可以利用await"等一等"的特性去讓程式等待await後面的函式做完以後再執行下面的程式碼(當然,await必須要配合async使用),例如下面的小例子
async myfun(){
await this.setState({
data: '666'
});
}
7.什麼是immutable, 為什麼要使用它
-
Immutable Data 就是一旦建立,就不能再被更改的資料。對 Immutable 物件的任何修改或新增刪除操作都會返回一個新的 Immutable 物件
-
Immutable 實現的原理是 Persistent Data Structure (持久化資料結構),也就是使用舊資料建立新資料時,要保證舊資料同時可用且不變
TIP:當然,通過這一點,我們可以去做時間旅行,也就是以前呼叫之前存在過的舊資料。 -
同時為了避免 deepCopy 把所有節點都複製一遍帶來的效能損耗, Immutable 使用了 Structural Sharing···· (結構共享),即如果物件樹中一個節點發生變化,只修改這個節點和受它影響的父節點,其它節點則進行共享。
A
/ \
A B
/ \ / \
C D E F
//例如我們現在資料F發生改變,那麼他只會影響到B與A,其他不會受到影響的資料直接複製過來就好了無需重新進行操作,效能有所提升。
8. 什麼是 JSX
JSX是javascript的語法擴充套件。它就像一個擁有javascript全部功能的模板語言 在裡面可以使用js程式碼
它實現的原理就是react封裝了createElement(第一個引數是 標籤名,第二個引數是物件 包含了所有的屬性,第三個是子節點)。
9. React的diff演算法
React Diff 演算法的差異查詢實質是對兩個JavaScript物件(虛擬DOM和真實DOM)的差異查詢,所以React更新階段才會有Diff演算法的運用。
更多
10.React中介軟體(React-thunk , React-promise)
在React種有三個部分 :
(1)Reducer:純函式,只承擔計算 State 的功能,不合適承擔其他功能,也承擔不了,因為理論上,純函式不能進行讀寫操作。
(2)View:與 State 一一對應,可以看作 State 的視覺層,也不合適承擔其他功能。
(3)Action:存放資料的物件,即訊息的載體,只能被別人操作,自己不能進行任何操作。
而想要在React種非同步請求資料,在Action中請求無疑是最完美的。即store.dispatch()方法,可以新增請求資料功能。而中介軟體就是一個函式,對store.dispatch方法進行了改造,在發出 Action 和執行 Reducer 這兩步之間,添加了其他功能。
redux-thunk
中介軟體,改造了store.dispatch,使得後者可以接受函式作為引數。與之相對應的redux-promise
返回一個 Promise 物件。
React-thunk的使用
11.裝飾器語法
- 什麼是裝飾器?
Decorator 是 ES7 的一個新語法,他可以對一些物件進行裝飾包裝然後返回一個被包裝過的物件,
可以裝飾的物件包括:類,屬性,方法等。
- 裝飾器的作用
裝飾器的作用就是為已經存在的函式或物件新增額外的功能。 裝飾器應用場景及理解:
裝飾器本質上是一個函式,它可以讓其他函式在不需要做任何程式碼變動的前提下增加額外功能 。
這裡主要介紹一下類裝飾器,使用類裝飾器可以減少一些程式碼的重複編寫。
此時裝飾器看起來更像是一個父類,但它又不是一個父類,因為被裝飾的類重寫一些生命週期函式的時候
裝飾器裡面的生命週期函式並不會被覆蓋執行。對於componentDidMount 來說,先執被裝飾類的
componentDidMount 再執行 裝飾器內的componentDidMount;對於componentWillUnmount 來講
先執行裝飾器的componentWillUnmount 再執行被裝飾的類的componentWillUnmount
裝飾器connect例項
關於裝飾器的安裝及引用在這裡並不做贅述,只介紹如何在React中使用裝飾器
@connect(state => ({ banner: state.banner}), dispatch => ({
getBanner() {
dispatch(getBannerAction)
},
}))
class PicturesWall extends React.Component {
componentDidMount() {
this.props.getBanner()
}
//使用 banner 變數
}
在這個類元件中,呼叫 componentDidMount 生命週期鉤子,觸發了connect 中的 getBanner 函式,並獲取了 redux 中的 banner 變數。在這裡 裝飾器connect 包裹了 PicturesWall 元件 並觸發一個非同步函式,將store中的 banner變數傳給元件
//函式式元件,換了種寫法,作用都一樣
const commodityclass = () => {
...
}
export default connect((state => ({ model_payload: state.model_payload})))(commodityclass)
12.React state 和 props 有什麼不同
props 是一個從外部傳進元件的引數,主要作為就是從父元件向子元件傳遞資料,它具有可讀性和不變性,只能通過外部元件主動傳入新的 props 來重新渲染子元件,否則子元件的 props 以及展現形式不會改變。
state 是元件自身的狀態,的主要作用是用於元件儲存、控制以及修改自己的狀態的一些資料,它只能在 constructor 中初始化,它算是元件的私有屬性,不可通過外部訪問和修改,只能通過元件內部的 this.setState 來修改,修改 state 屬性會導致元件的重新渲染。
- state 是元件自己管理資料,控制自己的狀態,可變;
- props 是外部傳入的資料引數,不可變;
13.React 的路由懶載入怎麼實現?
-
使用傳統的 import 的方式。可以在函式內 return 一個 import, 新增 webpackChunkName 的註釋,這樣 webpack 打包時就會將對應的檔案單獨打包,當函式執行時再去載入這個包。
return import( /* webpackChunkName: "lodash" */ 'lodash').then(_ => {}
-
使用 React.lazy 實現。匯入時呼叫 React.lazy 並給他一個函式引數,函式中返回 import React.lazy(() => import("./XXX"))。配合 Suspense 可以實現在模組未載入完成的時候給使用者一個提示。
14.類元件和函式元件有什麼區別
類元件可以使用其他特性,如狀態 state 和生命週期鉤子。
當元件只是接收 props 渲染到頁面時,就是無狀態元件,就屬於函式元件
函式元件的效能比類元件的效能要高, 因為類元件使用的時候要例項化,而函式元件直接執行函式取返回結果即可。為了提高效能,儘量使用函式元件。
函式元件沒有this,沒有生命週期,沒有狀態state,
類元件有this,有生命週期,有狀態state。
15.什麼是高階元件、受控元件、非受控元件?
高階元件
是個函式,輸出結果是個新元件,可以對輸入的元件進行加工,並返回一個具有特定功能的元件。
受控元件
相當於input中的value值通過state值獲取,onChange事件改變state中的value值。實現了雙向繫結,任意一方的資料發生變化,另一方也會隨之改變 。
非受控元件
不需要設定對應的state屬性,可通過ref來直接操作真實的dom。
16.vuex和redux的區別
表面區別就是vuex是通過將store注入到元件例項中,通過dispatch和commit來維護state的狀態,並可以通過mapstate和this.$store來讀取state資料。而redux則是需要通過connect將state和dispatch連線來對映state並操作state。redux沒有commit,直接通過dispatch派發一個action來維護state的資料。並且只能通過reducer一個函式來操作state。
rudex使用的是不可變資料;vuex是可變的資料。
rudex每次都是返回一個新的state;而vuex是直接改變state。