基礎概念類
1. 什么是 React?
React 是一個用于構建用戶界面的 JavaScript 庫,由 Facebook 開發(fā)并開源。它采用組件化的思想,允許開發(fā)者將復雜的 UI 拆分成多個小的、可復用的組件,通過組合這些組件來構建整個應用程序。React 使用虛擬 DOM(Virtual DOM)來提高渲染效率,通過比較新舊虛擬 DOM 的差異,只更新需要更新的真實 DOM 節(jié)點。
2. 什么是 JSX?它有什么作用?
JSX 是 JavaScript XML 的縮寫,它是一種 JavaScript 的語法擴展,允許在 JavaScript 代碼中編寫類似 XML 的標記。JSX 的作用主要有:
- 更直觀的 UI 描述:使代碼更接近 HTML 結構,方便開發(fā)者編寫和理解 UI 界面。
- 靜態(tài)檢查:可以在編譯時進行靜態(tài)檢查,提前發(fā)現(xiàn)一些錯誤。
- 與 JavaScript 無縫集成:可以在 JSX 中嵌入 JavaScript 表達式,實現(xiàn)動態(tài)內容的展示。
示例:
const element = <h1>Hello, {name}!</h1>;
3. 什么是虛擬 DOM(Virtual DOM)?為什么要使用它?
虛擬 DOM 是一種輕量級的 JavaScript 對象,它是真實 DOM 的抽象表示。虛擬 DOM 是一個樹形結構,每個節(jié)點對應一個真實的 DOM 元素。
使用虛擬 DOM 的原因:
- 提高性能:在更新 UI 時,直接操作真實 DOM 的代價較高。React 會先在虛擬 DOM 上進行修改,然后通過比較新舊虛擬 DOM 的差異,只更新需要更新的真實 DOM 節(jié)點,減少了真實 DOM 的操作次數(shù),從而提高了性能。
- 跨平臺:虛擬 DOM 是一個抽象的概念,不依賴于具體的平臺,可以方便地實現(xiàn)跨平臺開發(fā),如 React Native 就是基于虛擬 DOM 實現(xiàn)的。
組件相關類
1. React 組件有哪幾種類型?它們有什么區(qū)別?
React 組件主要分為兩類:函數(shù)組件和類組件。
-
函數(shù)組件:是一個純函數(shù),接收
props作為參數(shù),并返回一個 React 元素。函數(shù)組件沒有自己的狀態(tài)和生命周期方法,也被稱為無狀態(tài)組件。
示例:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
-
類組件:是一個繼承自
React.Component的類,它有自己的狀態(tài)和生命周期方法。類組件可以使用this.state來管理組件的狀態(tài),通過this.props接收外部傳遞的屬性。
示例:
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
區(qū)別:
-
狀態(tài)管理:函數(shù)組件沒有自己的狀態(tài),只能通過
props接收外部數(shù)據;類組件可以使用this.state管理組件的狀態(tài)。 -
生命周期方法:函數(shù)組件沒有生命周期方法;類組件有一系列的生命周期方法,如
componentDidMount、componentDidUpdate等。 - 代碼復雜度:函數(shù)組件代碼更簡潔,適合簡單的展示性組件;類組件代碼相對復雜,適合處理復雜的邏輯和狀態(tài)管理。
2. 什么是 props 和 state?它們有什么區(qū)別?
-
props:是properties的縮寫,用于在組件之間傳遞數(shù)據。props是只讀的,組件不能修改自己的props,只能通過父組件重新傳遞新的props來更新數(shù)據。 -
state:是組件內部的狀態(tài),用于管理組件自身的數(shù)據。state是可變的,組件可以通過this.setState方法來更新state,從而觸發(fā)組件的重新渲染。
區(qū)別:
-
數(shù)據來源:
props是從父組件傳遞過來的;state是組件內部自己管理的數(shù)據。 -
可變性:
props是只讀的;state是可變的。 -
使用場景:
props用于在組件之間傳遞數(shù)據;state用于管理組件內部的動態(tài)數(shù)據。
3. 如何在 React 中實現(xiàn)組件間通信?
-
父組件向子組件通信:通過
props傳遞數(shù)據。父組件將數(shù)據作為屬性傳遞給子組件,子組件通過props接收數(shù)據。
示例:
// 父組件
function Parent() {
const message = "Hello from parent";
return <Child message={message} />;
}
// 子組件
function Child(props) {
return <p>{props.message}</p>;
}
-
子組件向父組件通信:通過回調函數(shù)。父組件將一個回調函數(shù)作為
props傳遞給子組件,子組件在需要時調用該回調函數(shù)并傳遞數(shù)據給父組件。
示例:
// 父組件
function Parent() {
const handleChildData = (data) => {
console.log(data);
};
return <Child onData={handleChildData} />;
}
// 子組件
function Child(props) {
const sendData = () => {
props.onData("Hello from child");
};
return <button onClick={sendData}>Send Data</button>;
}
- 非父子組件通信:可以使用事件總線(Event Bus)、Context API 或狀態(tài)管理庫(如 Redux、MobX)來實現(xiàn)。
生命周期與 Hooks 類
1. 簡述 React 類組件的生命周期方法。
React 類組件的生命周期方法可以分為三個階段:掛載階段、更新階段和卸載階段。
-
掛載階段:組件被創(chuàng)建并插入到 DOM 中。
-
constructor:組件的構造函數(shù),用于初始化state和綁定事件處理函數(shù)。 -
static getDerivedStateFromProps:在組件掛載和更新時都會調用,用于根據props更新state。 -
render:渲染組件的 UI。 -
componentDidMount:組件掛載完成后調用,常用于發(fā)起網絡請求、訂閱事件等。
-
-
更新階段:組件的
props或state發(fā)生變化時,組件會重新渲染。-
static getDerivedStateFromProps:同上。 -
shouldComponentUpdate:用于決定組件是否需要重新渲染,返回true表示需要重新渲染,返回false表示不需要。 -
render:同上。 -
getSnapshotBeforeUpdate:在 DOM 更新之前調用,用于獲取 DOM 更新前的一些信息。 -
componentDidUpdate:組件更新完成后調用,常用于更新 DOM 或發(fā)起網絡請求。
-
-
卸載階段:組件從 DOM 中移除。
-
componentWillUnmount:組件卸載前調用,常用于清理定時器、取消訂閱等操作。
-
2. 什么是 React Hooks?常見的 Hooks 有哪些?
React Hooks 是 React 16.8 引入的新特性,它允許在不編寫 class 的情況下使用 state 和其他 React 特性。Hooks 可以讓你在不改變組件結構的情況下復用狀態(tài)邏輯,使代碼更加簡潔和可維護。
常見的 Hooks 有:
-
useState:用于在函數(shù)組件中添加state。
示例:
import React, { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
-
useEffect:用于在函數(shù)組件中處理副作用,如數(shù)據獲取、訂閱、定時器等。
示例:
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
return () => {
// 清理副作用
};
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
-
useContext:用于在函數(shù)組件中使用 Context API。 -
useReducer:是useState的替代方案,用于處理復雜的狀態(tài)邏輯。 -
useCallback:用于緩存函數(shù),避免在每次渲染時都重新創(chuàng)建函數(shù)。 -
useMemo:用于緩存計算結果,避免在每次渲染時都進行復雜的計算。
3. useState 和 useReducer 有什么區(qū)別?
-
使用場景:
-
useState適用于簡單的狀態(tài)管理,狀態(tài)的更新邏輯比較簡單,通常只涉及到對狀態(tài)的簡單修改。 -
useReducer適用于復雜的狀態(tài)管理,狀態(tài)的更新邏輯比較復雜,涉及到多個狀態(tài)的組合或復雜的計算。
-
-
語法:
-
useState使用一個初始值來初始化狀態(tài),并返回一個數(shù)組,數(shù)組的第一個元素是當前狀態(tài),第二個元素是更新狀態(tài)的函數(shù)。 -
useReducer使用一個 reducer 函數(shù)和一個初始狀態(tài)來初始化狀態(tài),并返回一個數(shù)組,數(shù)組的第一個元素是當前狀態(tài),第二個元素是觸發(fā)狀態(tài)更新的 dispatch 函數(shù)。
-
示例:
// useState
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
// useReducer
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
</div>
);
}
性能優(yōu)化類
1. 如何優(yōu)化 React 應用的性能?
-
使用
shouldComponentUpdate或React.memo:shouldComponentUpdate是類組件的生命周期方法,用于決定組件是否需要重新渲染;React.memo是函數(shù)組件的高階組件,用于淺比較props,如果props沒有變化,則不會重新渲染組件。 -
使用
React.lazy和Suspense:React.lazy用于動態(tài)導入組件,Suspense用于在組件加載時顯示加載提示,實現(xiàn)代碼分割,減少首屏加載時間。
示例:
const LazyComponent = React.lazy(() => import('./LazyComponent'));
function App() {
return (
<div>
<React.Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</React.Suspense>
</div>
);
}
-
避免不必要的渲染:盡量減少
state和props的變化,避免在render方法中進行復雜的計算。 - 使用事件委托:將事件處理函數(shù)綁定到父組件上,通過事件冒泡來處理子組件的事件,減少事件處理函數(shù)的數(shù)量。
- 優(yōu)化 CSS:避免使用內聯(lián)樣式,使用 CSS 類名來管理樣式,減少重排和重繪。
2. 什么是 React.memo?它和 shouldComponentUpdate 有什么區(qū)別?
-
React.memo:是一個高階組件,用于函數(shù)組件的性能優(yōu)化。它會對組件的props進行淺比較,如果props沒有變化,則不會重新渲染組件。
示例:
const MyComponent = React.memo((props) => {
return <div>{props.message}</div>;
});
-
區(qū)別:
-
適用組件類型:
React.memo適用于函數(shù)組件;shouldComponentUpdate適用于類組件。 -
比較方式:
React.memo進行淺比較;shouldComponentUpdate可以自定義比較邏輯,進行更復雜的比較。
-
適用組件類型:
其他類
1. 什么是 React Router?如何使用它實現(xiàn)路由功能?
React Router 是 React 官方推薦的路由庫,用于實現(xiàn)單頁面應用(SPA)的路由功能。它提供了不同的路由組件,如 BrowserRouter、HashRouter、Route、Link 等。
使用步驟:
- 安裝 React Router:
npm install react-router-dom - 引入必要的組件:
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
- 創(chuàng)建路由配置:
function App() {
return (
<Router>
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
</nav>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
</Router>
);
}
function Home() {
return <h1>Home Page</h1>;
}
function About() {
return <h1>About Page</h1>;
}
2. 什么是 Context API?它有什么作用?
Context API 是 React 提供的一種在組件樹中共享數(shù)據的方式,避免了通過 props 層層傳遞數(shù)據的繁瑣。它主要用于在多個組件之間共享一些全局數(shù)據,如用戶信息、主題顏色等。
使用步驟:
- 創(chuàng)建 Context:
const MyContext = React.createContext();
- 提供數(shù)據:
<MyContext.Provider value={/* 要共享的數(shù)據 */}>
{/* 子組件 */}
</MyContext.Provider>
- 消費數(shù)據:
// 類組件
class MyComponent extends React.Component {
static contextType = MyContext;
render() {
const value = this.context;
return <div>{value}</div>;
}
}
// 函數(shù)組件
function MyComponent() {
const value = useContext(MyContext);
return <div>{value}</div>;
}