2022最新前端常見react面試題合集
fetch封裝
npm install whatwg-fetch --save // 適配其他瀏覽器
npm install es6-promise
export const handleResponse = (response) => {
if (response.status === 403 || response.status === 401) {
const oauthurl = response.headers.get('locationUrl');
if (!_.isEmpty(oauthUrl)) {
window.location.href = oauthurl;
return;
}
}
if (!response.ok) {
return getErrorMessage(response).then(errorMessage => apiError(response.status, errorMessage));
}
if (isJson(response)) {
return response.json();
}
if (isText(response)) {
return response.text();
}
return response.blob();
};
const httpRequest = {
request: ({
method, headers, body, path, query,
}) => {
const options = {};
let url = path;
if (method) {
options.method = method;
}
if (headers) {
options.headers = {...options.headers,...headers};
}
if (body) {
options.body = body;
}
if (query) {
const params = Object.keys(query)
.map(k => `${k}=${query[k]}`)
.join('&');
url = url.concat(`?${params}`);
}
return fetch(url, Object.assign({}, options, { credentials: 'same-origin' })).then(handleResponse);
},
};
export default httpRequest;react性能優(yōu)化方案
- 重寫
shouldComponentUpdate來避免不必要的dom操作 - 使用
production版本的react.js - 使用
key來幫助React識別列表中所有子組件的最小變化
什么是 React Context?
Context 通過組件樹提供了一個傳遞數(shù)據(jù)的方法,從而避免了在每一個層級手動的傳遞 props 屬性。
何為 JSX
JSX 是 JavaScript 語法的一種語法擴展,并擁有 JavaScript 的全部功能。JSX 生產(chǎn) React "元素",你可以將任何的 JavaScript 表達式封裝在花括號里,然后將其嵌入到 JSX 中。在編譯完成之后,JSX 表達式就變成了常規(guī)的 JavaScript 對象,這意味著你可以在 if 語句和 for 循環(huán)內部使用 JSX,將它賦值給變量,接受它作為參數(shù),并從函數(shù)中返回它。
props 是什么
- react的核心思想是組件化,頁面被分成很多個獨立,可復用的組件
- 而組件就是一個函數(shù),可以接受一個參數(shù)作為輸入值,這個參數(shù)就是props,所以props就是從外部傳入組件內部的數(shù)據(jù)
- 由于react的單向數(shù)據(jù)流模式,所以props是從父組件傳入子組件的數(shù)據(jù)
應該在 React 組件的何處發(fā)起 Ajax 請求
在 React 組件中,應該在 componentDidMount 中發(fā)起網(wǎng)絡請求。這個方法會在組件第一次“掛載”(被添加到 DOM)時執(zhí)行,在組件的生命周期中僅會執(zhí)行一次。更重要的是,你不能保證在組件掛載之前 Ajax 請求已經(jīng)完成,如果是這樣,也就意味著你將嘗試在一個未掛載的組件上調用 setState,這將不起作用。在 componentDidMount 中發(fā)起網(wǎng)絡請求將保證這有一個組件可以更新了。
react 強制刷新
component.forceUpdate() 一個不常用的生命周期方法, 它的作用就是強制刷新
官網(wǎng)解釋如下
默認情況下,當組件的 state 或 props 發(fā)生變化時,組件將重新渲染。如果 render() 方法依賴于其他數(shù)據(jù),則可以調用 forceUpdate() 強制讓組件重新渲染。
調用 forceUpdate() 將致使組件調用 render() 方法,此操作會跳過該組件的 shouldComponentUpdate()。但其子組件會觸發(fā)正常的生命周期方法,包括 shouldComponentUpdate() 方法。如果標記發(fā)生變化,React 仍將只更新 DOM。
通常你應該避免使用 forceUpdate(),盡量在 render() 中使用 this.props 和 this.state。
shouldComponentUpdate 在初始化 和 forceUpdate 不會執(zhí)行
使用 React Hooks 好處是啥?
首先,Hooks 通常支持提取和重用跨多個組件通用的有狀態(tài)邏輯,而無需承擔高階組件或渲染 props 的負擔。Hooks 可以輕松地操作函數(shù)組件的狀態(tài),而不需要將它們轉換為類組件。
Hooks 在類中不起作用,通過使用它們,咱們可以完全避免使用生命周期方法,例如 componentDidMount、componentDidUpdate、componentWillUnmount。相反,使用像useEffect這樣的內置鉤子。
Redux內部原理 內部怎么實現(xiàn)dispstch一個函數(shù)的
以redux-thunk中間件作為例子,下面就是thunkMiddleware函數(shù)的代碼
// 部分轉為ES5代碼,運行middleware函數(shù)會返回一個新的函數(shù),如下:
return ({ dispatch, getState }) => {
// next實際就是傳入的dispatch
return function (next) {
return function (action) {
// redux-thunk核心
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
};
}
redux-thunk庫內部源碼非常的簡單,允許action是一個函數(shù),同時支持參數(shù)傳遞,否則調用方法不變
redux創(chuàng)建Store:通過combineReducers函數(shù)合并reducer函數(shù),返回一個新的函數(shù)combination(這個函數(shù)負責循環(huán)遍歷運行reducer函數(shù),返回全部state)。將這個新函數(shù)作為參數(shù)傳入createStore函數(shù),函數(shù)內部通過dispatch,初始化運行傳入的combination,state生成,返回store對象redux中間件:applyMiddleware函數(shù)中間件的主要目的就是修改dispatch函數(shù),返回經(jīng)過中間件處理的新的dispatch函數(shù)redux使用:實際就是再次調用循環(huán)遍歷調用reducer函數(shù),更新state
何為純函數(shù)(pure function)
一個純函數(shù)是一個不依賴于且不改變其作用域之外的變量狀態(tài)的函數(shù),這也意味著一個純函數(shù)對于同樣的參數(shù)總是返回同樣的結果。
如何配置 React-Router 實現(xiàn)路由切換
(1)使用<Route> 組件
路由匹配是通過比較 <Route> 的 path 屬性和當前地址的 pathname 來實現(xiàn)的。當一個 <Route> 匹配成功時,它將渲染其內容,當它不匹配時就會渲染 null。沒有路徑的 <Route> 將始終被匹配。
// when location = { pathname: '/about' }
<Route path='/about' component={About}/> // renders <About/>
<Route path='/contact' component={Contact}/> // renders null
<Route component={Always}/> // renders <Always/>(2)結合使用 <Switch> 組件和 <Route> 組件
<Switch> 用于將 <Route> 分組。
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
</Switch>
<Switch> 不是分組 <Route> 所必須的,但他通常很有用。 一個 <Switch> 會遍歷其所有的子 <Route>元素,并僅渲染與當前地址匹配的第一個元素。
(3)使用 <Link>、 <NavLink>、<Redirect> 組件
<Link> 組件來在你的應用程序中創(chuàng)建鏈接。無論你在何處渲染一個<Link> ,都會在應用程序的 HTML 中渲染錨(<a>)。
<Link to="/">Home</Link> // <a href='/'>Home</a>
是一種特殊類型的 當它的 to屬性與當前地址匹配時,可以將其定義為"活躍的"。
// location = { pathname: '/react' }
<NavLink to="/react" activeClassName="hurray">
React
</NavLink>
// <a href='/react' className='hurray'>React</a>當我們想強制導航時,可以渲染一個<Redirect>,當一個<Redirect>渲染時,它將使用它的to屬性進行定向。
在 React 中,何為 state
State 和 props 類似,但它是私有的,并且完全由組件自身控制。State 本質上是一個持有數(shù)據(jù),并決定組件如何渲染的對象。
react16版本的reconciliation階段和commit階段是什么
- reconciliation階段包含的主要工作是對current tree 和 new tree 做diff計算,找出變化部分。進行遍歷、對比等是可以中斷,歇一會兒接著再來。
- commit階段是對上一階段獲取到的變化部分應用到真實的DOM樹中,是一系列的DOM操作。不僅要維護更復雜的DOM狀態(tài),而且中斷后再繼續(xù),會對用戶體驗造成影響。在普遍的應用場景下,此階段的耗時比diff計算等耗時相對短。
類組件和函數(shù)組件之間的區(qū)別是啥?
- 類組件可以使用其他特性,如狀態(tài)
state和生命周期鉤子。 - 當組件只是接收
props渲染到頁面時,就是無狀態(tài)組件,就屬于函數(shù)組件,也被稱為啞組件或展示組件。
函數(shù)組件和類組件當然是有區(qū)別的,而且函數(shù)組件的性能比類組件的性能要高,因為類組件使用的時候要實例化,而函數(shù)組件直接執(zhí)行函數(shù)取返回結果即可。為了提高性能,盡量使用函數(shù)組件。
| 區(qū)別 | 函數(shù)組件 | 類組件 |
|---|---|---|
是否有 this | 沒有 | 有 |
| 是否有生命周期 | 沒有 | 有 |
是否有狀態(tài) state | 沒有 | 有 |
React-Router 4怎樣在路由變化時重新渲染同一個組件?
當路由變化時,即組件的props發(fā)生了變化,會調用componentWillReceiveProps等生命周期鉤子。那需要做的只是: 當路由改變時,根據(jù)路由,也去請求數(shù)據(jù):
class NewsList extends Component {
componentDidMount () {
this.fetchData(this.props.location);
}
fetchData(location) {
const type = location.pathname.replace('/', '') || 'top'
this.props.dispatch(fetchListData(type))
}
componentWillReceiveProps(nextProps) {
if (nextProps.location.pathname != this.props.location.pathname) {
this.fetchData(nextProps.location);
}
}
render () {
...
}
}利用生命周期componentWillReceiveProps,進行重新render的預處理操作。
react 生命周期
初始化階段:
- getDefaultProps:獲取實例的默認屬性
- getInitialState:獲取每個實例的初始化狀態(tài)
- componentWillMount:組件即將被裝載、渲染到頁面上
- render:組件在這里生成虛擬的 DOM 節(jié)點
- componentDidMount:組件真正在被裝載之后
運行中狀態(tài):
- componentWillReceiveProps:組件將要接收到屬性的時候調用
- shouldComponentUpdate:組件接受到新屬性或者新狀態(tài)的時候(可以返回 false,接收數(shù)據(jù)后不更新,阻止 render 調用,后面的函數(shù)不會被繼續(xù)執(zhí)行了)
- componentWillUpdate:組件即將更新不能修改屬性和狀態(tài)
- render:組件重新描繪
- componentDidUpdate:組件已經(jīng)更新
銷毀階段:
- componentWillUnmount:組件即將銷毀
shouldComponentUpdate 是做什么的,(react 性能優(yōu)化是哪個周期函數(shù)?)
shouldComponentUpdate 這個方法用來判斷是否需要調用 render 方法重新描繪 dom。因為 dom 的描繪非常消耗性能,如果我們能在 shouldComponentUpdate 方法中能夠寫出更優(yōu)化的 dom diff 算法,可以極大的提高性能。
在react17 會刪除以下三個生命周期
componentWillMount,componentWillReceiveProps , componentWillUpdate
非嵌套關系組件的通信方式?
即沒有任何包含關系的組件,包括兄弟組件以及不在同一個父級中的非兄弟組件。
- 可以使用自定義事件通信(發(fā)布訂閱模式)
- 可以通過redux等進行全局狀態(tài)管理
- 如果是兄弟組件通信,可以找到這兩個兄弟節(jié)點共同的父節(jié)點, 結合父子間通信方式進行通信。
在 Redux 中,何為 store
Store 是一個 javascript 對象,它保存了整個應用的 state。與此同時,Store 也承擔以下職責:
- 允許通過
getState()訪問 state - 運行通過
dispatch(action)改變 state - 通過
subscribe(listener)注冊 listeners - 通過
subscribe(listener)返回的函數(shù)處理 listeners 的注銷
react 最新版本解決了什么問題,增加了哪些東西
React 16.x的三大新特性 Time Slicing、Suspense、 hooks
- Time Slicing(解決CPU速度問題)使得在執(zhí)行任務的期間可以隨時暫停,跑去干別的事情,這個特性使得react能在性能極其差的機器跑時,仍然保持有良好的性能
- Suspense (解決網(wǎng)絡IO問題) 和lazy配合,實現(xiàn)異步加載組件。 能暫停當前組件的渲染, 當完成某件事以后再繼續(xù)渲染,解決從react出生到現(xiàn)在都存在的「異步副作用」的問題,而且解決得非的優(yōu)雅,使用的是 T異步但是同步的寫法,這是最好的解決異步問題的方式
- 提供了一個內置函數(shù)componentDidCatch,當有錯誤發(fā)生時,可以友好地展示 fallback 組件; 可以捕捉到它的子元素(包括嵌套子元素)拋出的異常; 可以復用錯誤組件。
(1)React16.8 加入hooks,讓React函數(shù)式組件更加靈活,hooks之前,React存在很多問題:
- 在組件間復用狀態(tài)邏輯很難
- 復雜組件變得難以理解,高階組件和函數(shù)組件的嵌套過深。
- class組件的this指向問題
- 難以記憶的生命周期
hooks很好的解決了上述問題,hooks提供了很多方法
- useState 返回有狀態(tài)值,以及更新這個狀態(tài)值的函數(shù)
- useEffect 接受包含命令式,可能有副作用代碼的函數(shù)。
- useContext 接受上下文對象(從 React.createContext返回的值)并返回當前上下文值,
- useReducer useState 的替代方案。接受類型為 (state,action)=> newState的reducer,并返回與dispatch方法配對的當前狀態(tài)。
- useCalLback 返回一個回憶的memoized版本,該版本僅在其中一個輸入發(fā)生更改時才會更改。純函數(shù)的輸入輸出確定性 o useMemo 純的一個記憶函數(shù) o useRef 返回一個可變的ref對象,其Current 屬性被初始化為傳遞的參數(shù),返回的 ref 對象在組件的整個生命周期內保持不變。
- useImperativeMethods 自定義使用ref時公開給父組件的實例值
- useMutationEffect 更新兄弟組件之前,它在React執(zhí)行其DOM改變的同一階段同步觸發(fā)
- useLayoutEffect DOM改變后同步觸發(fā)。使用它來從DOM讀取布局并同步重新渲染
(2)React16.9
- 重命名 Unsafe 的生命周期方法。新的 UNSAFE_前綴將有助于在代碼 review 和 debug 期間,使這些有問題的字樣更突出
- 廢棄 javascrip:形式的 URL。以javascript:開頭的URL 非常容易遭受攻擊,造成安全漏洞。
- 廢棄"Factory"組件。 工廠組件會導致 React 變大且變慢。
- act()也支持異步函數(shù),并且你可以在調用它時使用 await。
- 使用 <React.ProfiLer> 進行性能評估。在較大的應用中追蹤性能回歸可能會很方便
(3)React16.13.0
- 支持在渲染期間調用setState,但僅適用于同一組件
- 可檢測沖突的樣式規(guī)則并記錄警告
- 廢棄 unstable_createPortal,使用CreatePortal
- 將組件堆棧添加到其開發(fā)警告中,使開發(fā)人員能夠隔離bug并調試其程序,這可以清楚地說明問題所在,并更快地定位和修復錯誤。
什么是 React Fiber?
Fiber 是 React 16 中新的協(xié)調引擎或重新實現(xiàn)核心算法。它的主要目標是支持虛擬DOM的增量渲染。React Fiber 的目標是提高其在動畫、布局、手勢、暫停、中止或重用等方面的適用性,并為不同類型的更新分配優(yōu)先級,以及新的并發(fā)原語。
React Fiber 的目標是增強其在動畫、布局和手勢等領域的適用性。它的主要特性是增量渲染:能夠將渲染工作分割成塊,并將其分散到多個幀中。
到此這篇關于前端常見react面試題合集的文章就介紹到這了,更多相關react面試題內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
React Native中ScrollView組件輪播圖與ListView渲染列表組件用法實例分析
這篇文章主要介紹了React Native中ScrollView組件輪播圖與ListView渲染列表組件用法,結合實例形式詳細分析了ScrollView組件輪播圖與ListView渲染列表組件具體功能、使用方法與操作注意事項,需要的朋友可以參考下2020-01-01
react hooks實現(xiàn)防抖節(jié)流的方法小結
這篇文章主要介紹了react hooks實現(xiàn)防抖節(jié)流的幾種方法,文中通過代碼示例給大家講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下2024-04-04
高性能React開發(fā)React Server Components詳解
ReactServerComponents通過服務器端渲染、自動代碼分割等技術,實現(xiàn)了高性能的React開發(fā),它解決了客戶端數(shù)據(jù)請求鏈式延遲、敏感數(shù)據(jù)暴露風險等問題,提供了更好的用戶體驗和安全性,本文介紹高性能React開發(fā)React Server Components詳解,感興趣的朋友一起看看吧2025-03-03

