1. Context API
Context API 允许在组件树中共享数据,而无需通过props逐层传递。这对于共享主题、用户信息等全局状态非常有用。更多学习教程www.fgedu.net.cn
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
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 是一个高阶组件,用于缓存组件的渲染结果,避免不必要的重新渲染。
import React, { useState } from ‘react’;
// 普通组件
function RegularComponent({ name }) {
console.log(‘RegularComponent rendered’);
return
;
}
// 使用React.memo优化的组件
const MemoizedComponent = React.memo(function MemoizedComponent({ name }) {
console.log(‘MemoizedComponent rendered’);
return
;
});
// 父组件
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元素非常有用。
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
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
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允许我们将组件逻辑提取到可重用的函数中,提高代码复用性。
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
;
}
if (error) {
return
;
}
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元素。
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
)} />
);
}
// 应用组件
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性能优化可以提高应用的响应速度和用户体验。
# 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 (
);
}
author:www.itpux.com
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
