React基础知识(总结回顾一)
React知识框架图可以帮助理清React的核心概念及其相关技术。下面是一个大致的React知识框架图,按功能模块将React的核心知识进行分类,包括从基础到进阶的内容。
React 知识框架图:
+---------------------+
| React 基础 |
+---------------------+
|
|--- JSX语法
|--- 函数组件与类组件
|--- 渲染机制(虚拟DOM、渲染流程)
|--- 事件处理(onClick, onChange)
|--- 条件渲染与列表渲染
|--- 受控组件与非受控组件
|--- 基本的组件通信(props, state)
|
+---------------------+
| React Hooks |
+---------------------+
|
|--- useState
|--- useEffect
|--- useContext
|--- useRef
|--- useReducer
|--- useCallback
|--- useMemo
|
+---------------------+
| React 路由 |
+---------------------+
|
|--- React Router (v6)
|--- 路由配置(Route, Switch, Link)
|--- 嵌套路由与动态路由
|--- 重定向与路由守卫
|
+---------------------+
| 组件间通信 |
+---------------------+
|
|--- 父子组件通信(props)
|--- 子父组件通信(通过回调函数传递数据)
|--- Context API(跨层级共享状态)
|--- 自定义Hooks(共享逻辑)
|
+---------------------+
| 状态管理 |
+---------------------+
|
|--- useState / useReducer(局部状态)
|--- Redux(全局状态管理)
|--- Redux Toolkit
|--- MobX
|
+---------------------+
| 性能优化与调试 |
+---------------------+
|
|--- React.memo
|--- useMemo
|--- useCallback
|--- shouldComponentUpdate
|--- React Profiler
|--- 懒加载与代码分割(React.lazy & Suspense)
|
+---------------------+
| 高级功能 |
+---------------------+
|
|--- 动态导入(React.lazy)
|--- Suspense与错误边界
|--- React Portals
|--- HOC(高阶组件)
|--- Render Props
|--- 自定义Hooks
|--- Context API优化
|
+---------------------+
| 测试与部署 |
+---------------------+
|
|--- 单元测试(Jest, React Testing Library)
|--- 快照测试(Snapshot Testing)
|--- 端到端测试(Cypress)
|--- Webpack与Babel配置
|--- CI/CD与自动化部署
|
+---------------------+
| 配置与工具链 |
+---------------------+
|
|--- Webpack
|--- Babel
|--- ESLint / Prettier
|--- Create React App (CRA)
|--- Next.js / Gatsby
|
解释:
-
React基础:
- JSX语法:React的组件通常使用JSX(JavaScript XML),它允许你在JavaScript中写HTML。
- 函数组件与类组件:函数组件更为简洁,类组件在React中较为传统,但不再推荐使用。
- 渲染机制:React使用虚拟DOM优化UI渲染的效率,更新时对比虚拟DOM与真实DOM,尽量减少DOM操作。
- 受控组件与非受控组件:受控组件的值由React状态控制,非受控组件的值由DOM本身管理。
- 事件处理:React使用事件委托机制处理事件,减少内存使用并提高性能。
-
React Hooks:
useState
:用于管理组件内部的状态。useEffect
:用于处理副作用(例如数据请求、DOM操作等)。useContext
:用于跨越组件层级传递数据。useRef
:引用DOM元素或保存可变的状态。useReducer
:用于更复杂的状态管理。useCallback
和useMemo
:优化性能,避免不必要的渲染和计算。
-
React 路由:
- 使用
React Router
管理页面路由,支持动态路由、嵌套路由、重定向等。 - 通过
Link
组件实现页面跳转。
- 使用
-
组件间通信:
- Props:父组件通过
props
传递数据给子组件。 - 回调函数:子组件通过回调函数将数据传递回父组件。
- Context API:在多个组件间共享全局状态,避免层层传递
props
。
- Props:父组件通过
-
状态管理:
- 使用
useState
和useReducer
管理局部组件状态。 - Redux:用于全局状态管理,适合大型应用。
- Redux Toolkit:简化Redux的使用,减少样板代码。
- 使用
-
性能优化与调试:
- React.memo:避免函数组件的重复渲染。
- useMemo & useCallback:优化性能,避免不必要的计算和函数创建。
- React Profiler:帮助分析组件渲染性能。
- 懒加载与代码分割:通过
React.lazy
和Suspense
实现组件的懒加载,减少初次加载时的资源大小。
-
高级功能:
- React Portals:让子组件能够渲染到父组件之外的DOM节点中,常用于模态框、弹出层等场景。
- 高阶组件(HOC):一种用于复用组件逻辑的模式。
- Render Props:通过函数作为props传递数据,实现组件之间的共享逻辑。
- 自定义Hooks:封装复用逻辑,使代码更加模块化。
-
测试与部署:
- 单元测试:通过Jest和React Testing Library对组件进行单元测试。
- 快照测试:通过快照对比组件渲染结果,确保UI不会出现意外变动。
- 端到端测试:使用Cypress等工具进行端到端的UI测试。
- CI/CD:集成持续集成与持续部署,自动化构建和部署过程。
-
配置与工具链:
- Webpack:打包工具,帮助将多个文件打包成一个文件,提升加载性能。
- Babel:JavaScript转译工具,将ES6+代码转换为兼容浏览器的代码。
- ESLint & Prettier:静态代码分析和格式化工具,帮助保持代码质量。
- Next.js & Gatsby:基于React的框架,分别用于服务器端渲染(SSR)和静态网站生成。
总结:
这个框架图按模块从基础到进阶覆盖了React的各个方面。每个模块包含了React开发中最常用的工具、技术和概念。如果你在学习React,可以逐步深入每个领域并理解其细节,掌握这些知识将有助于你应对React相关的面试和项目开发。
下面详细解释React的基础和进阶知识点,并给出相关代码示例。
React基础
1. JSX语法
JSX(JavaScript XML)是React的核心语法扩展,允许我们在JavaScript中写类似HTML的代码。它被最终转换为React.createElement()
方法调用,生成虚拟DOM元素。
示例:
import React from 'react';
function Welcome() {
return <h1>Hello, world!</h1>; // JSX语法,返回一个h1元素
}
export default Welcome;
解释:
-
JSX语法看起来像HTML,但它实际是在背后转化成了
React.createElement()
调用,因此我们可以在其中使用JavaScript表达式,如:const name = 'Alice'; return <h1>Hello, {name}!</h1>;
2. 函数组件与类组件
- 函数组件:更简洁,推荐用于大部分React开发,尤其是配合Hooks。
- 类组件:传统的React组件形式,通常用于需要状态或生命周期钩子的场景,但已被函数组件和Hooks取代。
函数组件示例:
import React from 'react';
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
export default Greeting;
类组件示例:
import React, { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
export default Greeting;
解释:
- 函数组件更加简洁且易于维护。
- 类组件提供了更多生命周期方法和状态管理的能力。
3. 渲染机制
React通过虚拟DOM提高性能。每次状态或props发生变化时,React会生成一个虚拟DOM并与旧的虚拟DOM进行比较(称为“diffing”算法),然后仅将差异部分更新到真实DOM中,从而最小化DOM操作,提高性能。
示例:
const [count, setCount] = useState(0);
// 虚拟DOM会在每次状态更新时进行对比,只更新不同的部分
return <button onClick={() => setCount(count + 1)}>{count}</button>;
4. 受控组件与非受控组件
- 受控组件:组件的值由React的状态管理,每当输入发生变化时,React状态会更新。
- 非受控组件:表单元素的值由DOM管理,React不直接干预。
受控组件示例:
import React, { useState } from 'react';
function ControlledInput() {
const [value, setValue] = useState('');
const handleChange = (e) => setValue(e.target.value);
return <input type="text" value={value} onChange={handleChange} />;
}
export default ControlledInput;
非受控组件示例:
import React, { useRef } from 'react';
function UncontrolledInput() {
const inputRef = useRef();
const handleSubmit = () => {
alert(inputRef.current.value); // 通过ref获取值
};
return (
<div>
<input ref={inputRef} />
<button onClick={handleSubmit}>Submit</button>
</div>
);
}
export default UncontrolledInput;
5. 事件处理
React使用事件委托机制处理事件,事件处理函数通过props传递给子组件,并且自动绑定到DOM元素。
示例:
function Button() {
const handleClick = () => {
alert('Button clicked!');
};
return <button onClick={handleClick}>Click Me</button>;
}
export default Button;
React Hooks
1. useState
useState
是一个用于管理组件内部状态的Hook。
示例:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // 初始化count为0
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default Counter;
2. useEffect
useEffect
用于处理副作用,比如数据获取、订阅等,类似于类组件中的componentDidMount
和componentDidUpdate
。
示例:
import React, { useState, useEffect } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds(prev => prev + 1);
}, 1000);
return () => clearInterval(interval); // 清理副作用
}, []); // 只有在组件挂载时执行
return <p>Timer: {seconds} seconds</p>;
}
export default Timer;
3. useContext
useContext
用于访问Context
中的数据,避免通过层层props
传递数据。
示例:
const ThemeContext = React.createContext('light');
function ThemedComponent() {
const theme = useContext(ThemeContext); // 使用useContext获取值
return <p>Current theme is {theme}</p>;
}
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemedComponent />
</ThemeContext.Provider>
);
}
export default App;
4. useRef
useRef
用于引用DOM元素或存储可变数据(如计时器ID),并且不会触发重新渲染。
示例:
import React, { useRef } from 'react';
function FocusInput() {
const inputRef = useRef();
const handleFocus = () => {
inputRef.current.focus(); // 让input获取焦点
};
return (
<div>
<input ref={inputRef} />
<button onClick={handleFocus}>Focus the input</button>
</div>
);
}
export default FocusInput;
5. useReducer
useReducer
用于处理复杂的状态管理,类似于Redux的Reducer。
示例:
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
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>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
</div>
);
}
export default Counter;
6. useCallback
和 useMemo
这两个Hooks用于性能优化:
useCallback
:缓存函数,避免每次渲染都创建新的函数。useMemo
:缓存计算结果,避免每次渲染都进行昂贵的计算。
示例:
import React, { useState, useCallback, useMemo } from 'react';
function ExpensiveComponent({ count }) {
const calculateFactorial = useMemo(() => {
return factorial(count);
}, [count]);
const increment = useCallback(() => {
alert('Button clicked');
}, []); // 只有依赖项变化时才重新创建函数
return (
<div>
<p>Factorial: {calculateFactorial}</p>
<button onClick={increment}>Click</button>
</div>
);
}
function factorial(num) {
if (num === 0) return 1;
return num * factorial(num - 1);
}
React 路由
1. React Router
React Router用于在React应用中实现路由功能。
示例:
import React from 'react';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
function Home() {
return <h2>Home Page</h2>;
}
function About() {
return <h2>About Page</h2>;
}
function App() {
return (
<Router>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
</Switch>
</Router>
);
}
export default App;
解释:
BrowserRouter
:包裹整个应用
,管理路由。
Route
:定义页面路由和匹配路径。Switch
:确保只渲染一个Route
。
组件间通信
1. Props
父组件通过props
传递数据给子组件。
示例:
function Parent() {
const message = 'Hello from Parent!';
return <Child message={message} />;
}
function Child({ message }) {
return <p>{message}</p>;
}
2. 回调函数
子组件通过回调函数传递数据给父组件。
示例:
function Parent() {
const [data, setData] = useState('');
const handleData = (childData) => {
setData(childData);
};
return (
<div>
<Child onData={handleData} />
<p>Data from child: {data}</p>
</div>
);
}
function Child({ onData }) {
return <button onClick={() => onData('Data from Child')}>Send Data</button>;
}
3. Context API
用于跨层级组件共享状态。
示例:
const ThemeContext = React.createContext('light');
function Child() {
const theme = useContext(ThemeContext);
return <p>Current theme: {theme}</p>;
}
function Parent() {
return (
<ThemeContext.Provider value="dark">
<Child />
</ThemeContext.Provider>
);
}
状态管理
1. useState 和 useReducer
如前面所述,useState
用于简单的局部状态管理,useReducer
用于复杂的状态管理。
2. Redux
Redux是全局状态管理工具,适合大型应用。
示例:
import { createStore } from 'redux';
const initialState = { count: 0 };
function reducer(state = initialState, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
default:
return state;
}
}
const store = createStore(reducer);
store.dispatch({ type: 'INCREMENT' });
console.log(store.getState()); // { count: 1 }
3. Redux Toolkit
简化了Redux的使用,减少了样板代码。
示例:
import { createSlice, configureStore } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: { count: 0 },
reducers: {
increment: (state) => {
state.count += 1;
},
},
});
const store = configureStore({
reducer: counterSlice.reducer,
});
store.dispatch(counterSlice.actions.increment());
console.log(store.getState()); // { count: 1 }
以上是React中的一些基础和进阶知识点的详细解释与代码示例。掌握这些内容将帮助你在开发React应用时更加高效,并在面试中展示你扎实的React基础。
————————————————————————————————
在React的前端面试中,以下是常见的面试点,每个点都涉及React的核心概念、使用方法和代码示例。理解并熟练应用这些概念,将有助于你在React面试中表现出色。
1. 组件的生命周期(componentDidMount
, useEffect
等)
React的生命周期方法在类组件中用来处理组件的挂载、更新和卸载等操作。函数组件通过useEffect
Hook来模拟生命周期方法。
类组件生命周期方法:
componentDidMount
:组件挂载后执行。componentDidUpdate
:组件更新时执行。componentWillUnmount
:组件卸载时执行。
class MyComponent extends React.Component {
componentDidMount() {
console.log('Component mounted');
}
componentDidUpdate(prevProps, prevState) {
console.log('Component updated');
}
componentWillUnmount() {
console.log('Component will unmount');
}
render() {
return <div>Component Lifecycle</div>;
}
}
函数组件中使用useEffect
:
useEffect
Hook在函数组件中用于处理副作用,比如数据加载、定时器、订阅等。它代替了类组件中的componentDidMount
、componentDidUpdate
、componentWillUnmount
等生命周期方法。
import { useEffect } from 'react';
function MyComponent() {
useEffect(() => {
console.log('Component mounted');
// Cleanup function
return () => {
console.log('Component will unmount');
};
}, []); // 空数组表示仅在挂载和卸载时执行
return <div>Component Lifecycle</div>;
}
2. Hooks的使用与原理
React的Hooks API允许在函数组件中使用状态和副作用等特性,而无需写类组件。常用的Hooks有useState
、useEffect
、useContext
、useReducer
等。
useState
:
useState
用于管理函数组件的局部状态。
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // 初始状态为0
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
useEffect
:
useEffect
用于处理副作用(如数据请求、DOM操作等)。它可以模拟componentDidMount
、componentDidUpdate
和componentWillUnmount
。
import { useState, useEffect } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds(prev => prev + 1);
}, 1000);
return () => clearInterval(interval); // 清理副作用
}, []); // 空数组表示仅在挂载和卸载时执行
return <p>Timer: {seconds} seconds</p>;
}
useContext
:
useContext
用于跨层级组件共享数据,而不必通过props
逐层传递。
import { useContext } from 'react';
const MyContext = React.createContext();
function Child() {
const value = useContext(MyContext); // 获取Context值
return <p>{value}</p>;
}
function Parent() {
return (
<MyContext.Provider value="Hello from context">
<Child />
</MyContext.Provider>
);
}
useReducer
:
useReducer
用于管理更复杂的状态逻辑,类似于useState
,但适用于更复杂的状态管理。
import { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
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>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
</div>
);
}
3. 组件通信(props
传递数据、useContext
跨组件通信)
React组件可以通过props
进行父子组件的数据传递,也可以使用useContext
跨组件共享状态。
通过props
传递数据:
父组件通过props
将数据传递给子组件。
function Parent() {
const message = 'Hello from Parent';
return <Child message={message} />;
}
function Child({ message }) {
return <p>{message}</p>;
}
通过useContext
进行跨组件通信:
useContext
让我们可以通过Context
在整个应用中共享数据,避免逐层传递props
。
const ThemeContext = React.createContext('light');
function Child() {
const theme = useContext(ThemeContext); // 获取当前主题
return <p>Current Theme: {theme}</p>;
}
function Parent() {
return (
<ThemeContext.Provider value="dark">
<Child />
</ThemeContext.Provider>
);
}
4. 虚拟DOM的工作原理
React通过虚拟DOM提高性能。每次组件状态更新时,React会生成一个虚拟DOM(内存中的对象),然后与之前的虚拟DOM进行比较(即"diffing"算法)。最后,React会计算出最小的DOM操作来更新实际的DOM。
- 虚拟DOM:React将UI渲染为虚拟DOM树,避免直接操作真实DOM,从而提高性能。
5. 事件处理(onClick
, onChange
等)
React的事件处理是通过事件代理机制实现的。事件的绑定与浏览器原生事件不同,React会将事件处理函数直接传递给虚拟DOM。
function MyButton() {
const handleClick = () => {
alert('Button clicked!');
};
return <button onClick={handleClick}>Click Me</button>;
}
6. 条件渲染与列表渲染(map
, &&
运算符)
条件渲染:
通过条件语句来决定是否渲染某些内容。
function MyComponent({ isLoggedIn }) {
return isLoggedIn ? <p>Welcome back!</p> : <p>Please log in.</p>;
}
列表渲染:
通过map
方法渲染列表。
function List({ items }) {
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
7. 受控组件与非受控组件的区别
- 受控组件:组件的状态由React的状态管理。
- 非受控组件:表单元素的值由DOM自己管理,React不直接干预。
受控组件:
function Form() {
const [value, setValue] = useState('');
const handleChange = (event) => {
setValue(event.target.value);
};
return <input value={value} onChange={handleChange} />;
}
非受控组件:
function Form() {
const inputRef = useRef();
const handleSubmit = () => {
alert(inputRef.current.value);
};
return <input ref={inputRef} />;
}
8. React性能优化(React.memo
, useMemo
, useCallback
)
React.memo
:
React.memo
是一个高阶组件,用于避免函数组件的重复渲染。
const Child = React.memo(function Child({ count }) {
console.log('Child rendered');
return <p>Count: {count}</p>;
});
useMemo
:
useMemo
用于缓存计算结果,避免不必要的计算。
function ExpensiveComponent({ number }) {
const computedValue = useMemo(() => expensiveCalculation(number), [number]);
return <p>{computedValue}</p>;
}
useCallback
:
useCallback
用于缓存函数实例,避免每次渲染都创建新的函数。
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []); // 只有依赖项变化时才会重新创建函数
9. React Router 和 Redux
React Router:
React Router用于管理React应用的路由。
import
{ BrowserRouter as Router, Route, Switch } from 'react-router-dom';
function App() {
return (
<Router>
<Switch>
<Route path="/about" component={AboutPage} />
<Route path="/" component={HomePage} />
</Switch>
</Router>
);
}
Redux:
Redux是一个用于全局状态管理的库,它使用一个集中式的store来存储状态,并通过dispatch
触发状态更新。
import { createStore } from 'redux';
const initialState = { count: 0 };
function reducer(state = initialState, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
default:
return state;
}
}
const store = createStore(reducer);
store.dispatch({ type: 'INCREMENT' });
console.log(store.getState()); // { count: 1 }
总结
这些是React面试中常见的面试点和相关概念,包括生命周期、Hooks、组件通信、虚拟DOM、事件处理、条件渲染、性能优化等。掌握这些核心知识,不仅可以帮助你更好地理解React的工作原理,还能在面试中展示你的React开发技能。