重生之我在chatgpt中学习React 第六天-前端-E先生的博客
Java
MySQL
大数据
Python
前端
黑科技
大语言模型
    首页 >> 互联网 >> 前端

重生之我在chatgpt中学习React 第六天

[导读]:React 学习指南 - 第六天1. React 组件生命周期虽然在函数组件中,React 使用 Hooks 代替了类组件的生命周期方法,但了解类组件的生命周期方法对于理解 React 的工作机制仍然非常重要。今天我们将学习类组件中的生命周期方法,以及它们在函数组件中的等价物。1.1 类组件的生命周期方法类组件的生命周期方法大致分为三个阶段...

React 学习指南 - 第六天

1. React 组件生命周期

虽然在函数组件中,React 使用 Hooks 代替了类组件的生命周期方法,但了解类组件的生命周期方法对于理解 React 的工作机制仍然非常重要。今天我们将学习类组件中的生命周期方法,以及它们在函数组件中的等价物。

1.1 类组件的生命周期方法

类组件的生命周期方法大致分为三个阶段:挂载(Mounting)更新(Updating)卸载(Unmounting)

  • 挂载阶段

    • constructor(): 用于初始化状态和绑定事件处理器。

    • static getDerivedStateFromProps(): 在渲染之前调用,可以用于根据 props 更新 state

    • componentDidMount(): 组件挂载后调用,通常用于获取数据或设置订阅。

  • 更新阶段

    • static getDerivedStateFromProps(): 当 props 改变时调用,用于更新 state

    • shouldComponentUpdate(): 在每次渲染前调用,控制组件是否需要重新渲染。

    • render(): 用于渲染组件的 UI。

    • getSnapshotBeforeUpdate(): 在 DOM 更新之前调用,可以读取一些 DOM 数据并返回给 componentDidUpdate

    • componentDidUpdate(): 在组件更新后调用,常用于处理副作用或同步更新。

  • 卸载阶段

    • componentWillUnmount(): 组件卸载前调用,通常用于清理订阅、定时器等。

1.2 生命周期方法示例

以下是一个简单的类组件生命周期方法的示例:

import React, { Component } from 'react';

class Timer extends Component {
  constructor(props) {
    super(props);
    this.state = { seconds: 0 };
  }

  componentDidMount() {
    this.interval = setInterval(() => {
      this.setState({ seconds: this.state.seconds + 1 });
    }, 1000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    return <div>Time: {this.state.seconds} seconds</div>;
  }
}

export default Timer;
  • componentDidMount 中,我们设置了一个定时器,每秒钟更新一次 state

  • componentWillUnmount 中,我们清理了定时器,避免内存泄漏。

1.3 函数组件的生命周期钩子

对于函数组件,React 通过 Hooks 来替代类组件中的生命周期方法。我们使用 useEffect 来处理副作用,useState 来管理状态。

  • useEffect 用于处理副作用,它相当于类组件中的 componentDidMountcomponentDidUpdatecomponentWillUnmount

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 <div>Time: {seconds} seconds</div>;
}

export default Timer;
  • useEffect 的返回函数相当于 componentWillUnmount,用于清理副作用(比如清除定时器)。

  • 空数组 [] 作为依赖项,表示副作用只在组件挂载时执行一次。

2. React 异常处理与 Error Boundaries

错误边界(Error Boundaries)是 React 16 引入的一个特性,用于捕获 JavaScript 错误,避免整个应用崩溃。

2.1 Error Boundaries 基本概念

错误边界是一个能够捕获其子组件树中 JavaScript 错误并展示回退 UI 的组件。它可以捕获并处理运行时错误,防止崩溃。

Error Boundary 必须是一个类组件,并实现两个生命周期方法:

  • static getDerivedStateFromError(error):用于更新状态,展示回退 UI。

  • componentDidCatch(error, info):记录错误信息,可以用于日志记录。

import React, { Component } from 'react';

class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true }; // 更新状态以显示回退 UI
  }

  componentDidCatch(error, info) {
    console.error('Error occurred:', error, info);
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>; // 错误时展示的回退 UI
    }

    return this.props.children; // 正常渲染子组件
  }
}

function BuggyComponent() {
  throw new Error('I am a bug!');
}

function App() {
  return (
    <ErrorBoundary>
      <BuggyComponent />
    </ErrorBoundary>
  );
}

export default App;
  • ErrorBoundary 组件捕获子组件中的错误并显示回退 UI。

  • 如果 BuggyComponent 抛出错误,ErrorBoundary 会捕获并显示 "Something went wrong"。

2.2 Error Boundaries 的局限性
  • 错误边界只能捕获渲染过程中的错误、生命周期方法中的错误和构造函数中的错误,无法捕获事件处理函数中的错误。

  • 可以通过 try-catch 块或 .catch() 来处理事件中的错误。

3. React Portals

React Portals 允许你将子节点渲染到 DOM 树中不同的位置,而不是直接在父组件的 DOM 树中。

这对于处理模态框、弹出窗口、工具提示等非常有用。

3.1 基本用法

ReactDOM.createPortal 是一个创建 Portal 的 API,它接收两个参数:

  • 要渲染的子节点。

  • 目标 DOM 节点(可以是任何 DOM 节点)。

import React from 'react';
import ReactDOM from 'react-dom';

function Modal() {
  return ReactDOM.createPortal(
    <div className="modal">
      <h2>Modal Window</h2>
      <p>This is a modal!</p>
    </div>,
    document.getElementById('modal-root') // 目标 DOM 节点
  );
}

function App() {
  return (
    <div>
      <h1>My App</h1>
      <Modal />
    </div>
  );
}

export default App;
  • createPortalModal 组件渲染到 modal-root DOM 节点(可能在 index.html 中定义)。

3.2 Portal 的用途

Portal 可以用于以下情况:

  • 弹出层和模态框。

  • Toast 通知。

  • 动态插入其他 UI 元素。

4. React 代码分割(Code Splitting)

随着应用的增长,加载所有代码可能导致性能问题。React 提供了代码分割的机制,通过懒加载(React.lazy)将应用拆分成多个小块,只加载用户当前需要的部分。

4.1 使用 React.lazySuspense

前面我们已经学习过如何使用 React.lazySuspense 来进行代码分割。今天我们进一步深入了解如何将路由与代码分割结合。

import React, { Suspense } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

const Home = React.lazy(() => import('./Home'));
const About = React.lazy(() => import('./About'));

function App() {
  return (
    <Router>
      <Suspense fallback={<div>Loading...</div>}>
        <Switch>
          <Route path="/" exact component={Home} />
          <Route path="/about" component={About} />
        </Switch>
      </Suspense>
    </Router>
  );
}

export default App;
  • 在这个例子中,HomeAbout 组件只有在用户访问相应的路由时才会被加载,而不是在应用启动时一次性加载所有内容。

5. 小结

  • React 生命周期:你了解了类组件中的生命周期方法,并学习了如何通过 useEffect 在函数组件中模拟相同的生命周期行为。

  • Error Boundaries:通过使用错误边界(Error Boundaries),你学会了如何捕获组件中的错误,防止应用崩溃,并展示回退 UI。

  • Portals:你学会了如何使用 React Portals 渲染子组件到 DOM 树中的不同位置,适用于弹出层和模态框等。

  • 代码分割:通过 React.lazySuspense,你掌握了如何进行代码分割,按需加载组件,提升应用性能。

今天的学习让你更好地理解了 React 生命周期、错误处理和代码优化技巧,你可以在构建更复杂的应用时更加得心应手。

image.png

本文来自E先生的博客,如若转载,请注明出处:https://javajz.cn

留言区

联系人:
手   机:
内   容:
验证码:

历史留言

欢迎加Easy的QQ