1. 首页 > IT综合教程 > 正文

it教程FG145-React高级特性

1. Context API

Context API 允许在组件树中共享数据,而无需通过props逐层传递。这对于共享主题、用户信息等全局状态非常有用。更多学习教程www.fgedu.net.cn

// Context API 示例
import React, { createContext, useContext, useState } from ‘react’;

// 创建Context
const ThemeContext = createContext();

// Context Provider组件
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState(‘light’);

const toggleTheme = () => {
setTheme(prevTheme => prevTheme === ‘light’ ? ‘dark’ : ‘light’);
};

return (

{children}

);
}

// 自定义Hook,方便使用Context
export function useTheme() {
const context = useContext(ThemeContext);
if (!context) {
throw new Error(‘useTheme must be used within a ThemeProvider’);
}
return context;
}

// 使用Context的组件
function ThemedButton() {
const { theme, toggleTheme } = useTheme();

return (

);
}

// 应用组件
function App() {
return (

Context API Example


);
}

export default App;

2. 高级Hooks

React提供了多种高级Hooks,如useReducer、useCallback、useMemo、useRef等,用于处理复杂的状态管理和性能优化。学习交流加群风哥微信: itpux-com

// 高级Hooks示例
import React, { useReducer, useCallback, useMemo, useRef, useEffect } from ‘react’;

// useReducer 示例
function counterReducer(state, action) {
switch (action.type) {
case ‘increment’:
return { count: state.count + 1 };
case ‘decrement’:
return { count: state.count – 1 };
case ‘reset’:
return { count: 0 };
default:
return state;
}
}

function Counter() {
const [state, dispatch] = useReducer(counterReducer, { count: 0 });

return (

useReducer Example

Count: {state.count}



);
}

// useCallback 和 useMemo 示例
function ExpensiveComponent({ items, onItemClick }) {
// useMemo 缓存计算结果
const sortedItems = useMemo(() => {
console.log(‘Sorting items…’);
return […items].sort((a, b) => a – b);
}, [items]);

return (

Sorted Items

    {sortedItems.map(item => (

  • onItemClick(item)}>
    {item}
  • ))}

);
}

function ParentComponent() {
const [count, setCount] = React.useState(0);
const [items, setItems] = React.useState([3, 1, 4, 1, 5, 9, 2, 6]);

// useCallback 缓存函数
const handleItemClick = useCallback((item) => {
console.log(‘Item clicked:’, item);
}, []);

return (

useCallback and useMemo Example

Count: {count}

);
}

// useRef 示例
function RefExample() {
const inputRef = useRef(null);
const countRef = useRef(0);

useEffect(() => {
// 访问DOM元素
inputRef.current.focus();
}, []);

const increment = () => {
// 使用ref存储不触发重新渲染的值
countRef.current += 1;
console.log(‘Count:’, countRef.current);
};

return (

useRef Example


Ref count: {countRef.current} (won’t update in UI)

);
}

// 应用组件
function App() {
return (



);
}

export default App;

3. React.memo与性能优化

React.memo 是一个高阶组件,用于缓存组件的渲染结果,避免不必要的重新渲染。

// React.memo 示例
import React, { useState } from ‘react’;

// 普通组件
function RegularComponent({ name }) {
console.log(‘RegularComponent rendered’);
return

Hello, {name}!

;
}

// 使用React.memo优化的组件
const MemoizedComponent = React.memo(function MemoizedComponent({ name }) {
console.log(‘MemoizedComponent rendered’);
return

Hello, {name}!

;
});

// 父组件
function ParentComponent() {
const [count, setCount] = useState(0);
const [name, setName] = useState(‘World’);

return (

React.memo Example

Count: {count}



setName(e.target.value)}
placeholder=”Enter name”
/>

Regular Component:

Memoized Component:

);
}

// 应用组件
function App() {
return (

);
}

export default App;

// 注意:当点击”Increment Count”按钮时,RegularComponent会重新渲染,
// 而MemoizedComponent不会,因为它的props(name)没有变化。
// 当修改输入框中的name时,两个组件都会重新渲染,因为props发生了变化。

4. Portals

Portals 允许将组件的子元素渲染到DOM树中的另一个位置,而不是作为组件的直接子节点。这对于模态框、弹出菜单等UI元素非常有用。

// Portals 示例
import React, { useState } from ‘react’;
import ReactDOM from ‘react-dom’;

// 模态框组件
function Modal({ isOpen, onClose, children }) {
if (!isOpen) return null;

// 使用Portal将模态框渲染到body的末尾
return ReactDOM.createPortal(


{children}

,
document.body // 渲染到body元素
);
}

// 应用组件
function App() {
const [isModalOpen, setIsModalOpen] = useState(false);

return (

Portals Example

setIsModalOpen(false)}>

Modal Title

This is a modal dialog rendered using React Portals.

Portals allow us to render components outside of their parent DOM hierarchy.

);
}

export default App;

5. Suspense与代码分割

Suspense 允许组件在等待异步操作完成时显示占位符,结合React.lazy()可以实现代码分割,减少初始加载时间。学习交流加群风哥QQ113257174

// Suspense与代码分割示例
import React, { useState, Suspense, lazy } from ‘react’;

// 使用React.lazy()进行代码分割
const LazyComponent = lazy(() => import(‘./LazyComponent’));
const AnotherLazyComponent = lazy(() => import(‘./AnotherLazyComponent’));

// 占位符组件
function LoadingSpinner() {
return (

);
}

// 应用组件
function App() {
const [showLazy, setShowLazy] = useState(false);
const [showAnotherLazy, setShowAnotherLazy] = useState(false);

return (

Suspense and Code Splitting Example

}>
{showLazy && }
{showAnotherLazy && }

);
}

export default App;

// LazyComponent.js
// export default function LazyComponent() {
// return (
//

//

Lazy Component

//

This component was loaded lazily using React.lazy() and Suspense.

//

// );
// }

// AnotherLazyComponent.js
// export default function AnotherLazyComponent() {
// return (
//

//

Another Lazy Component

//

This is another component loaded lazily.

//

// );
// }

6. 错误边界

错误边界是一种React组件,用于捕获子组件树中的JavaScript错误,防止整个应用崩溃。

// 错误边界示例
import React, { useState } from ‘react’;

// 错误边界组件
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null };
}

static getDerivedStateFromError(error) {
// 更新状态,下次渲染时显示错误UI
return { hasError: true, error };
}

componentDidCatch(error, errorInfo) {
// 可以在这里记录错误信息
console.error(‘Error caught by ErrorBoundary:’, error, errorInfo);
}

render() {
if (this.state.hasError) {
// 自定义错误UI
return (

Something went wrong!

Error: {this.state.error?.toString()}

);
}

return this.props.children;
}
}

// 会抛出错误的组件
function BuggyComponent() {
const [count, setCount] = useState(0);

if (count === 5) {
// 模拟错误
throw new Error(‘Intentional error for testing Error Boundary’);
}

return (

Buggy Component

Count: {count}

);
}

// 应用组件
function App() {
return (

Error Boundary Example

Click the button below to increment the count. At count = 5, an error will be thrown.



Other Content

This content is not affected by the error in the BuggyComponent.

);
}

export default App;

7. 自定义Hooks

自定义Hooks允许我们将组件逻辑提取到可重用的函数中,提高代码复用性。

// 自定义Hooks示例
import React, { useState, useEffect, useCallback } from ‘react’;

// 自定义Hook:useLocalStorage
function useLocalStorage(key, initialValue) {
// 从localStorage读取初始值
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error(‘Error reading localStorage:’, error);
return initialValue;
}
});

// 更新localStorage
const setValue = useCallback((value) => {
try {
// 允许value是一个函数,类似于useState
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
window.localStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
console.error(‘Error writing to localStorage:’, error);
}
}, [key, storedValue]);

return [storedValue, setValue];
}

// 自定义Hook:useFetch
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
const fetchData = async () => {
setLoading(true);
setError(null);

try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(‘Network response was not ok’);
}
const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};

fetchData();
}, [url]);

return { data, loading, error };
}

// 使用自定义Hooks的组件
function LocalStorageExample() {
const [name, setName] = useLocalStorage(‘name’, ‘World’);

return (

useLocalStorage Example

setName(e.target.value)}
placeholder=”Enter your name”
style={{ padding: ‘8px’, margin: ’10px 0′ }}
/>

Hello, {name}! Your name is stored in localStorage.

);
}

function FetchExample() {
const { data, loading, error } = useFetch(‘https://jsonplaceholder.typicode.com/todos/1’);

if (loading) {
return

Loading…

;
}

if (error) {
return

Error: {error}

;
}

return (

useFetch Example

ID: {data.id}

Title: {data.title}

Completed: {data.completed ? ‘Yes’ : ‘No’}

);
}

// 应用组件
function App() {
return (

Custom Hooks Example


);
}

export default App;

8. Render Props模式

Render Props模式是一种在React组件间共享代码的技术,通过props传递一个函数,该函数返回要渲染的React元素。

// Render Props模式示例
import React, { useState } from ‘react’;

// 带Render Props的组件
function MouseTracker({ render }) {
const [position, setPosition] = useState({ x: 0, y: 0 });

const handleMouseMove = (e) => {
setPosition({ x: e.clientX, y: e.clientY });
};

return (


{render(position)}

);
}

// 使用Render Props的组件
function MousePositionDisplay() {
return (

Mouse Position Display

(

Mouse position: ({position.x}, {position.y})

)} />

);
}

function CatChaser() {
return (

Cat Chaser

(
Kitten
)} />

);
}

// 应用组件
function App() {
return (

Render Props Pattern Example

Move your mouse over the boxes below:


);
}

export default App;

9. 高阶组件

高阶组件(HOC)是一个接收组件并返回新组件的函数,用于重用组件逻辑。更多学习教程公众号风哥教程itpux_com

// 高阶组件示例
import React, { useState, useEffect } from ‘react’;

// 高阶组件:withLoading
function withLoading(Component) {
return function WithLoadingComponent({ isLoading, …props }) {
if (isLoading) {
return (

);
}
return ;
};
}

// 高阶组件:withErrorHandling
function withErrorHandling(Component) {
return function WithErrorHandlingComponent({ error, …props }) {
if (error) {
return (

Error

{error}

);
}
return ;
};
}

// 原始组件
function UserList({ users }) {
return (

    {users.map(user => (

  • {user.name} ({user.email})
  • ))}

);
}

// 应用高阶组件
const UserListWithLoading = withLoading(UserList);
const UserListWithErrorHandling = withErrorHandling(UserListWithLoading);

// 应用组件
function App() {
const [users, setUsers] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
const fetchUsers = async () => {
setIsLoading(true);
setError(null);

try {
const response = await fetch(‘https://jsonplaceholder.typicode.com/users’);
if (!response.ok) {
throw new Error(‘Failed to fetch users’);
}
const data = await response.json();
setUsers(data);
} catch (err) {
setError(err.message);
} finally {
setIsLoading(false);
}
};

fetchUsers();
}, []);

return (

High-Order Components Example

);
}

export default App;

10. React性能优化最佳实践

React性能优化可以提高应用的响应速度和用户体验。

# React性能优化最佳实践

# 1. 使用React.memo
– 缓存组件渲染结果,避免不必要的重新渲染
– 适用于纯展示组件

# 2. 使用useCallback和useMemo
– useCallback:缓存函数引用
– useMemo:缓存计算结果
– 避免在每次渲染时创建新的函数和对象

# 3. 合理使用useState和useReducer
– 对于复杂状态,使用useReducer代替useState
– 避免频繁更新状态

# 4. 代码分割
– 使用React.lazy()和Suspense
– 按需加载组件,减少初始加载时间

# 5. 虚拟列表
– 对于长列表,使用虚拟滚动
– 只渲染可见区域的元素
– 推荐库:react-window, react-virtualized

# 6. 减少不必要的DOM操作
– 使用CSS而非JavaScript动画
– 避免频繁修改DOM样式
– 使用transform和opacity进行动画

# 7. 优化渲染条件
– 使用短路求值(&&)和条件渲染
– 避免在渲染过程中进行复杂计算

# 8. 使用键(key)属性
– 在列表中使用唯一的key
– 帮助React识别哪些元素被添加、删除或修改

# 9. 避免内联对象和函数
– 不要在JSX中直接定义对象和函数
– 将它们移到组件外部或使用useMemo/useCallback

# 10. 监控性能
– 使用React DevTools Profiler
– 识别性能瓶颈
– 针对性优化

# 代码示例

// 优化前
function BadExample() {
// 每次渲染都会创建新的对象和函数
return (

);
}

// 优化后
const buttonStyle = { color: ‘red’ };

function GoodExample() {
// 使用useCallback缓存函数
const handleClick = React.useCallback(() => {
console.log(‘Clicked’);
}, []);

return (

);
}

生产环境风哥建议:在生产环境中,应使用生产模式构建React应用,这会自动进行代码压缩和优化。同时,应监控应用性能,及时发现和解决性能问题。

风哥风哥提示:React的高级特性可以帮助我们构建更复杂、更高效的应用程序。掌握这些特性对于成为一名优秀的React开发者至关重要。

author:www.itpux.com

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息