在掌握了 React 的基础知识后,我们可以进一步探索 React 的高级特性和最佳实践。这些特性将帮助你构建更高效、可维护和可扩展的 React 应用。本文重点介绍 Hooks、Context、Refs 和高阶组件等核心高级特性。
1. Hooks:函数组件的强大工具
Hooks 是 React 16.8 引入的新特性,允许你在函数组件中使用状态和其他 React 特性。
useState
useState
用于在函数组件中添加状态。
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffect
useEffect
用于在函数组件中执行副作用操作(如数据获取、订阅等)。
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
2. Context:跨组件传递数据
Context 提供了一种在组件树中传递数据的方法,而不必手动在每个层级传递 props。
const ThemeContext = React.createContext('light');
function ThemedButton() {
return (
<ThemeContext.Consumer>
{theme => <button className={theme}>I am styled by theme context!</button>}
</ThemeContext.Consumer>
);
}
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemedButton />
</ThemeContext.Provider>
);
}
3. Refs:访问 DOM 节点
Refs 提供了一种访问 DOM 节点或 React 元素的方式。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount() {
this.myRef.current.focus();
}
render() {
return <input type="text" ref={this.myRef} />;
}
}
4. 高阶组件(HOC):复用组件逻辑
高阶组件是一个函数,接受一个组件并返回一个新的组件。它用于复用组件逻辑。
function withSubscription(WrappedComponent, selectData) {
return class extends React.Component {
constructor(props) {
super(props);
this.state = {
data: selectData(DataSource, props)
};
}
componentDidMount() {
DataSource.addChangeListener(this.handleChange);
}
componentWillUnmount() {
DataSource.removeChangeListener(this.handleChange);
}
handleChange = () => {
this.setState({
data: selectData(DataSource, this.props)
});
}
render() {
return <WrappedComponent data={this.state.data} {...this.props} />;
}
};
}
5. 渲染属性(Render Props):共享代码
渲染属性是一种在组件之间共享代码的技术,通过一个值为函数的 prop 来实现。
class DataProvider extends React.Component {
state = {
data: 'Some data'
};
render() {
return this.props.render(this.state);
}
}
function App() {
return (
<DataProvider render={data => (
<h1>{data}</h1>
)}/>
);
}
6. React Router:实现路由
React Router 是一个用于在 React 应用中实现路由的库。
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
function App() {
return (
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
</Switch>
</Router>
);
}
7. Redux:状态管理
Redux 是一个状态管理库,通常与 React 一起使用。它提供了一个全局的状态容器,使得状态管理更加可预测和可维护。
import { createStore } from 'redux';
import { Provider, connect } from 'react-redux';
// Action
const increment = () => ({ type: 'INCREMENT' });
// Reducer
const counter = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1;
default:
return state;
}
};
// Store
const store = createStore(counter);
// Component
function Counter({ count, increment }) {
return (
<div>
<p>{count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}
// Connect
const mapStateToProps = state => ({ count: state });
const mapDispatchToProps = { increment };
const ConnectedCounter = connect(mapStateToProps, mapDispatchToProps)(Counter);
// App
function App() {
return (
<Provider store={store}>
<ConnectedCounter />
</Provider>
);
}
8. React Testing:测试组件
React 提供了测试工具和库来测试组件的行为和输出。
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});
9. React Portals:渲染到 DOM 层次结构之外
Portals 提供了一种将子节点渲染到父组件 DOM 层次结构之外的 DOM 节点的方式。
function Modal({ children }) {
return ReactDOM.createPortal(
<div className="modal">
{children}
</div>,
document.getElementById('modal-root')
);
}
10. Error Boundaries:捕获错误
错误边界是 React 组件,用于捕获子组件树中的 JavaScript 错误,并显示备用 UI。
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
logErrorToMyService(error, errorInfo);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
11. React Fragments:分组子元素
Fragments 允许你将多个子元素分组,而无需向 DOM 添加额外的节点。
function Columns() {
return (
<React.Fragment>
<td>Hello</td>
<td>World</td>
</React.Fragment>
);
}
12. React.memo:优化渲染性能
React.memo
是一个高阶组件,用于优化函数组件的渲染性能,避免不必要的重新渲染。
const MyComponent = React.memo(function MyComponent(props) {
/* render using props */
});
13. useReducer:复杂状态逻辑
useReducer
是 useState
的替代方案,适用于复杂的状态逻辑。
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:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</>
);
}
14. useCallback 和 useMemo:性能优化
useCallback
和 useMemo
用于优化函数组件的性能。
useCallback
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);
useMemo
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
15. React.lazy 和 Suspense:动态加载组件
React.lazy
允许你动态加载组件,Suspense
用于在组件加载时显示备用内容。
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<React.Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</React.Suspense>
);
}
16. React.StrictMode:突出潜在问题
React.StrictMode
是一个用于突出显示应用中潜在问题的工具。
function App() {
return (
<React.StrictMode>
<div>
<ComponentOne />
<ComponentTwo />
</div>
</React.StrictMode>
);
}
17. React 18 新特性
React 18 引入了并发渲染、自动批处理、新的根 API 等新特性。
import { createRoot } from 'react-dom/client';
const container = document.getElementById('root');
const root = createRoot(container);
root.render(<App />);
结语
本文深入探讨了 React 的高级特性,包括Hooks、Context、Refs、高阶组件、渲染属性、路由管理和状态管理、路由管理、状态管理、测试、Portals、错误边界和性能优化工具。通过掌握这些技术,你将能够构建更高效、可维护和可扩展的 React 应用。继续学习和实践,你将充分发挥 React 的强大功能!