【前端】深入浅出的React.js详解

打印 上一主题 下一主题

主题 882|帖子 882|积分 2648

React 是一个用于构建用户界面的 JavaScript 库,由 Facebook 开辟并维护。随着 React 的不停演进,官方文档也在不停更新和完善。本文将详细解读最新的 React 官方文档,涵盖核心概念、新特性、最佳实践等内容,帮助开辟者更好地理解和使用 React。

1. React 核心概念

1.1 组件

组件是 React 应用的基本构建块。组件可以是类组件或函数组件,每个组件负责渲染一部门用户界面。
1.1.1 函数组件

函数组件是最简单的组件情势,担当输入(props)并返回 JSX。
  1. function Welcome(props) {
  2.   return <h1>Hello, {props.name}</h1>;
  3. }
复制代码
1.1.2 类组件

类组件是通过继承 React.Component 类来界说的,可以包罗状态和生命周期方法。
  1. class Welcome extends React.Component {
  2.   render() {
  3.     return <h1>Hello, {this.props.name}</h1>;
  4.   }
  5. }
复制代码
1.2 JSX

JSX 是一种在 JavaScript 中编写类似 HTML 代码的语法扩展。React 使用 JSX 来形貌 UI 的结构。
  1. const element = <h1>Hello, world!</h1>;
复制代码
1.3 Props

Props 是组件之间传递数据的方式。父组件通过 props 将数据传递给子组件。
  1. function Welcome(props) {
  2.   return <h1>Hello, {props.name}</h1>;
  3. }
  4. const element = <Welcome name="Sara" />;
复制代码
1.4 State

State 是组件内部的数据存储,用于跟踪组件的状态变革。状态的变革会触发组件的重新渲染。
1.4.1 类组件中的状态

在类组件中,状态通过 state 属性来管理。
  1. class Counter extends React.Component {
  2.   constructor(props) {
  3.     super(props);
  4.     this.state = { count: 0 };
  5.   }
  6.   increment = () => {
  7.     this.setState(prevState => ({ count: prevState.count + 1 }));
  8.   };
  9.   render() {
  10.     return (
  11.       <div>
  12.         <p>Count: {this.state.count}</p>
  13.         <button onClick={this.increment}>Increment</button>
  14.       </div>
  15.     );
  16.   }
  17. }
复制代码
1.4.2 函数组件中的状态

在函数组件中,使用 useState 钩子来管理状态。
  1. import React, { useState } from 'react';
  2. function Counter() {
  3.   const [count, setCount] = useState(0);
  4.   const increment = () => {
  5.     setCount(count + 1);
  6.   };
  7.   return (
  8.     <div>
  9.       <p>Count: {count}</p>
  10.       <button onClick={increment}>Increment</button>
  11.     </div>
  12.   );
  13. }
复制代码
2. 新特性

2.1 Concurrent Mode

Concurrent Mode 是 React 的一个实验性功能,旨在进步应用的响应性和性能。Concurrent Mode 允许 React 在后台执行工作,并在必要时停止和恢复这些工作。
2.1.1 Suspense

Suspense 是 Concurrent Mode 的一个重要特性,用于处理异步数据加载。通过 Suspense 组件,可以在数据加载完成之前体现一个加载指示器。
  1. import React, { Suspense } from 'react';
  2. import { fetchData } from './api';
  3. function DataFetcher() {
  4.   const data = useDataLoader();
  5.   return <p>Data: {data}</p>;
  6. }
  7. function App() {
  8.   return (
  9.     <Suspense fallback={<p>Loading...</p>}>
  10.       <DataFetcher />
  11.     </Suspense>
  12.   );
  13. }
  14. function useDataLoader() {
  15.   const [data, setData] = useState(null);
  16.   useEffect(() => {
  17.     fetchData().then(data => setData(data));
  18.   }, []);
  19.   if (!data) {
  20.     throw new Promise(resolve => setTimeout(resolve, 1000));
  21.   }
  22.   return data;
  23. }
复制代码
2.2 Hooks

Hooks 是 React 16.8 引入的新特性,允许在函数组件中使用状态和其他 React 特性。
2.2.1 useState

useState 钩子用于在函数组件中添加状态。
  1. import React, { useState } from 'react';
  2. function Counter() {
  3.   const [count, setCount] = useState(0);
  4.   const increment = () => {
  5.     setCount(count + 1);
  6.   };
  7.   return (
  8.     <div>
  9.       <p>Count: {count}</p>
  10.       <button onClick={increment}>Increment</button>
  11.     </div>
  12.   );
  13. }
复制代码
2.2.2 useEffect

useEffect 钩子用于在函数组件中执行副作用操纵,如发起网络请求、设置定时器等。
  1. import React, { useState, useEffect } from 'react';
  2. function DataFetcher() {
  3.   const [data, setData] = useState(null);
  4.   useEffect(() => {
  5.     fetch('https://api.example.com/data')
  6.       .then(response => response.json())
  7.       .then(data => setData(data));
  8.   }, []);
  9.   return (
  10.     <div>
  11.       {data ? (
  12.         <p>Data: {data}</p>
  13.       ) : (
  14.         <p>Loading...</p>
  15.       )}
  16.     </div>
  17.   );
  18. }
复制代码
2.2.3 useContext

useContext 钩子用于在函数组件中使用 Context。
  1. import React, { createContext, useContext } from 'react';
  2. const ThemeContext = createContext('light');
  3. function ThemedButton() {
  4.   const theme = useContext(ThemeContext);
  5.   return <button style={{ background: theme }}>Button</button>;
  6. }
  7. function App() {
  8.   return (
  9.     <ThemeContext.Provider value="dark">
  10.       <ThemedButton />
  11.     </ThemeContext.Provider>
  12.   );
  13. }
复制代码
3. 生命周期方法

生命周期方法是类组件中的一系列方法,用于在组件的不同阶段执行特定的操纵。函数组件中使用钩子来实现类似的功能。
3.1 类组件中的生命周期方法

3.1.1 componentDidMount

在组件挂载后立即调用,通常用于发起网络请求或设置定时器。
  1. class DataFetcher extends React.Component {
  2.   state = {
  3.     data: null
  4.   };
  5.   componentDidMount() {
  6.     fetch('https://api.example.com/data')
  7.       .then(response => response.json())
  8.       .then(data => this.setState({ data }));
  9.   }
  10.   render() {
  11.     return (
  12.       <div>
  13.         {this.state.data ? (
  14.           <p>Data: {this.state.data}</p>
  15.         ) : (
  16.           <p>Loading...</p>
  17.         )}
  18.       </div>
  19.     );
  20.   }
  21. }
复制代码
3.1.2 componentDidUpdate

在组件更新后立即调用,可以用于比力新旧状态或属性,执行相应的操纵。
  1. class DataFetcher extends React.Component {
  2.   state = {
  3.     data: null,
  4.     id: 1
  5.   };
  6.   componentDidUpdate(prevProps, prevState) {
  7.     if (prevState.id !== this.state.id) {
  8.       fetch(`https://api.example.com/data/${this.state.id}`)
  9.         .then(response => response.json())
  10.         .then(data => this.setState({ data }));
  11.     }
  12.   }
  13.   changeId = () => {
  14.     this.setState(prevState => ({ id: prevState.id + 1 }));
  15.   };
  16.   render() {
  17.     return (
  18.       <div>
  19.         {this.state.data ? (
  20.           <p>Data: {this.state.data}</p>
  21.         ) : (
  22.           <p>Loading...</p>
  23.         )}
  24.         <button onClick={this.changeId}>Change ID</button>
  25.       </div>
  26.     );
  27.   }
  28. }
复制代码
3.1.3 componentWillUnmount

在组件卸载前调用,通常用于整理定时器或取消网络请求。
  1. class Timer extends React.Component {
  2.   state = {
  3.     seconds: 0
  4.   };
  5.   interval = null;
  6.   componentDidMount() {
  7.     this.interval = setInterval(() => {
  8.       this.setState(prevState => ({ seconds: prevState.seconds + 1 }));
  9.     }, 1000);
  10.   }
  11.   componentWillUnmount() {
  12.     clearInterval(this.interval);
  13.   }
  14.   render() {
  15.     return <p>Seconds: {this.state.seconds}</p>;
  16.   }
  17. }
复制代码
3.2 函数组件中的生命周期方法

3.2.1 useEffect

useEffect 钩子用于在函数组件中执行副作用操纵,如发起网络请求、设置定时器等。
3.2.1.1 模拟 componentDidMount

在组件挂载后执行操纵:
  1. import React, { useState, useEffect } from 'react';
  2. function DataFetcher() {
  3.   const [data, setData] = useState(null);
  4.   useEffect(() => {
  5.     fetch('https://api.example.com/data')
  6.       .then(response => response.json())
  7.       .then(data => setData(data));
  8.   }, []); // 空数组表示只在组件挂载时执行一次
  9.   return (
  10.     <div>
  11.       {data ? (
  12.         <p>Data: {data}</p>
  13.       ) : (
  14.         <p>Loading...</p>
  15.       )}
  16.     </div>
  17.   );
  18. }
复制代码
3.2.1.2 模拟 componentDidUpdate

在组件更新后执行操纵:
  1. import React, { useState, useEffect } from 'react';
  2. function DataFetcher() {
  3.   const [data, setData] = useState(null);
  4.   const [id, setId] = useState(1);
  5.   useEffect(() => {
  6.     fetch(`https://api.example.com/data/${id}`)
  7.       .then(response => response.json())
  8.       .then(data => setData(data));
  9.   }, [id]); // 依赖数组包含 id,表示当 id 变化时重新执行
  10.   const changeId = () => {
  11.     setId(id + 1);
  12.   };
  13.   return (
  14.     <div>
  15.       {data ? (
  16.         <p>Data: {data}</p>
  17.       ) : (
  18.         <p>Loading...</p>
  19.       )}
  20.       <button onClick={changeId}>Change ID</button>
  21.     </div>
  22.   );
  23. }
复制代码
3.2.1.3 模拟 componentWillUnmount

在组件卸载前执行整理操纵:
  1. import React, { useState, useEffect } from 'react';
  2. function Timer() {
  3.   const [seconds, setSeconds] = useState(0);
  4.   useEffect(() => {
  5.     const interval = setInterval(() => {
  6.       setSeconds(prevSeconds => prevSeconds + 1);
  7.     }, 1000);
  8.     return () => clearInterval(interval); // 清理定时器
  9.   }, []); // 空数组表示只在组件挂载时执行一次
  10.   return <p>Seconds: {seconds}</p>;
  11. }
复制代码
4. 最佳实践

4.1 代码分割和懒加载

通过代码分割和懒加载,可以优化应用的初始加载时间和性能。
  1. import React, { Suspense, lazy } from 'react';
  2. const OtherComponent = lazy(() => import('./OtherComponent'));
  3. function App() {
  4.   return (
  5.     <div>
  6.       <Suspense fallback={<div>Loading...</div>}>
  7.         <OtherComponent />
  8.       </Suspense>
  9.     </div>
  10.   );
  11. }
复制代码
4.2 避免不必要的渲染

通过 React.memo 和 PureComponent,可以避免不必要的组件重新渲染。
4.2.1 React.memo

React.memo 是一个高阶组件,用于优化函数组件的性能。
  1. import React from 'react';
  2. const MyComponent = React.memo(function MyComponent(props) {
  3.   /* 只在 props 发生变化时重新渲染 */
  4.   return <div>{props.value}</div>;
  5. });
复制代码
4.2.2 PureComponent

PureComponent 是一个基类,用于优化类组件的性能。
  1. import React from 'react';
  2. class MyComponent extends React.PureComponent {
  3.   render() {
  4.     /* 只在 props 或 state 发生变化时重新渲染 */
  5.     return <div>{this.props.value}</div>;
  6.   }
  7. }
复制代码
4.3 使用 useMemo 和 useCallback

useMemo 和 useCallback 钩子可以用于优化性能,避免不必要的计算和函数创建。
4.3.1 useMemo

useMemo 用于缓存计算结果,避免不必要的计算。
  1. import React, { useMemo } from 'react';
  2. function MyComponent({ list }) {
  3.   const sortedList = useMemo(() => list.sort(), [list]);
  4.   return <div>{sortedList.join(', ')}</div>;
  5. }
复制代码
4.3.2 useCallback

useCallback 用于缓存函数,避免不必要的函数创建。
  1. import React, { useCallback } from 'react';
  2. function MyComponent({ onIncrement }) {
  3.   const handleIncrement = useCallback(() => {
  4.     onIncrement();
  5.   }, [onIncrement]);
  6.   return <button onClick={handleIncrement}>Increment</button>;
  7. }
复制代码
4.4 错误界限

错误界限是一种 React 组件,可以捕获并处理其子组件树中抛出的 JavaScript 错误。
  1. class ErrorBoundary extends React.Component {
  2.   constructor(props) {
  3.     super(props);
  4.     this.state = { hasError: false };
  5.   }
  6.   static getDerivedStateFromError(error) {
  7.     return { hasError: true };
  8.   }
  9.   componentDidCatch(error, errorInfo) {
  10.     logErrorToMyService(error, errorInfo);
  11.   }
  12.   render() {
  13.     if (this.state.hasError) {
  14.       return <h1>Something went wrong.</h1>;
  15.     }
  16.     return this.props.children;
  17.   }
  18. }
  19. function App() {
  20.   return (
  21.     <ErrorBoundary>
  22.       <MyWidget />
  23.     </ErrorBoundary>
  24.   );
  25. }
复制代码
5. 示例代码

以下是一些综合示例,展示了如安在 React 中使用不同的特性和最佳实践。
5.1 类组件示例

  1. class DataFetcher extends React.Component {
  2.   state = {
  3.     data: null,
  4.     id: 1
  5.   };
  6.   componentDidMount() {
  7.     this.fetchData();
  8.   }
  9.   componentDidUpdate(prevProps, prevState) {
  10.     if (prevState.id !== this.state.id) {
  11.       this.fetchData();
  12.     }
  13.   }
  14.   componentWillUnmount() {
  15.     this.abortController.abort();
  16.   }
  17.   fetchData = () => {
  18.     this.abortController = new AbortController();
  19.     fetch(`https://api.example.com/data/${this.state.id}`, { signal: this.abortController.signal })
  20.       .then(response => response.json())
  21.       .then(data => this.setState({ data }))
  22.       .catch(error => console.error('Fetch error:', error));
  23.   };
  24.   changeId = () => {
  25.     this.setState(prevState => ({ id: prevState.id + 1 }));
  26.   };
  27.   render() {
  28.     return (
  29.       <div>
  30.         {this.state.data ? (
  31.           <p>Data: {this.state.data}</p>
  32.         ) : (
  33.           <p>Loading...</p>
  34.         )}
  35.         <button onClick={this.changeId}>Change ID</button>
  36.       </div>
  37.     );
  38.   }
  39. }
复制代码
5.2 函数组件示例

  1. import React, { useState, useEffect, useCallback } from 'react';
  2. function DataFetcher() {
  3.   const [data, setData] = useState(null);
  4.   const [id, setId] = useState(1);
  5.   useEffect(() => {
  6.     const abortController = new AbortController();
  7.     fetch(`https://api.example.com/data/${id}`, { signal: abortController.signal })
  8.       .then(response => response.json())
  9.       .then(data => setData(data))
  10.       .catch(error => console.error('Fetch error:', error));
  11.     return () => abortController.abort(); // 清理请求
  12.   }, [id]);
  13.   const changeId = useCallback(() => {
  14.     setId(id + 1);
  15.   }, [id]);
  16.   return (
  17.     <div>
  18.       {data ? (
  19.         <p>Data: {data}</p>
  20.       ) : (
  21.         <p>Loading...</p>
  22.       )}
  23.       <button onClick={changeId}>Change ID</button>
  24.     </div>
  25.   );
  26. }
复制代码
6. 总结

React 是一个强盛的库,用于构建用户界面。通过理解核心概念、新特性和最佳实践,开辟者可以更高效地使用 React 构建高性能和响应式的应用。本文详细解读了最新的 React 官方文档,涵盖了组件、JSX、Props、State、生命周期方法、Hooks、Concurrent Mode 等内容,并提供了示例代码和最佳实践。
附录



  • React 官方文档:React 文档
  • React Hooks 文档:React Hooks
  • MDN Web 文档:React 简介

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

南七星之家

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表