react相关知识

1.类组件和函数组件

(1)类组件

javascript 复制代码
import React, { Component } from 'react';

class UserProfile extends Component {
  constructor(props) {
    super(props);
    this.state = {
      userData: null,
      isLoading: true,
    };
    this.timerId = null;
  }

  componentDidMount() {
    // 模拟 API 调用
    this.timerId = setTimeout(() => {
      this.setState({
        userData: { name: 'John Doe', age: 28 },
        isLoading: false
      });
    }, 2000);
  }

  componentWillUnmount() {
    // 清理工作:清除定时器
    clearTimeout(this.timerId);
  }

  render() {
    const { isLoading, userData } = this.state;

    if (isLoading) {
      return <div>Loading user profile...</div>;
    }

    return (
      <div>
        <h2>Welcome, {userData.name}!</h2>
        <p>Age: {userData.age}</p>
        <p>From: {this.props.city}</p> {/* 使用从父组件传来的 props */}
      </div>
    );
  }
}

export default UserProfile;

(2)函数组件

javascript 复制代码
import React, { useState, useEffect } from 'react';

const UserProfile = ({ city }) => {
  // 使用 useState 替代 this.state
  const [userData, setUserData] = useState(null);
  const [isLoading, setIsLoading] = useState(true);

  // useEffect 替代生命周期方法
  useEffect(() => {
    // componentDidMount 的逻辑(以及 componentDidUpdate 的相关逻辑)
    const timerId = setTimeout(() => {
      setUserData({ name: 'John Doe', age: 28 });
      setIsLoading(false);
    }, 2000);

    // cleanup 函数:替代 componentWillUnmount
    return () => {
      clearTimeout(timerId);
    };
  }, []); // 空依赖数组表示只在组件挂载时执行

  if (isLoading) {
    return <div>Loading user profile...</div>;
  }

  return (
    <div>
      <h2>Welcome, {userData.name}!</h2>
      <p>Age: {userData.age}</p>
      <p>From: {city}</p>
    </div>
  );
};

export default UserProfile;

2.高阶组件

高阶组件是一个函数,它接收一个组件作为参数,并返回一个新的增强型组件。

简单来说:高阶组件是用于组件复用的高级技巧,它本质上是一个包装器(wrapper)

javascript 复制代码
const EnhancedComponent = higherOrderComponent(WrappedComponent);

为了解决 React 中的逻辑复用问题。在自定义 Hooks 出现之前,这是 React 中主要的逻辑复用方式。

应用:

  • 权限控制: 利用高阶组件的 条件渲染特性可以对页面进行权限控制,权限控制一般分为两个维度:页面级别和 页面元素级别
  • **组件渲染性能追踪:**借助父组件子组件生命周期规则捕获子组件的生命周期,可以方便的对某个组件的渲染时间进行记录
  • 页面复用

3.哪些方法会触发 React 重新渲染?重新渲染 render 会做些什么?

  • **setState()方法被调用:**但是这里有个点值得关注,执行 setState 的时候不一定会重新渲染。当 setState 传入 null 时,并不会触发 render。
  • 父组件重新渲染:只要父组件重新渲染了,即使传入子组件的 props 未发生变化,那么子组件也会重新渲染,进而触发 render

重新渲染 render 会做些什么?

  • 会对新旧 VNode 进行对比,也就是我们所说的Diff算法。
  • 对新旧两棵树进行一个深度优先遍历,这样每一个节点都会一个标记,在到深度遍历的时候,每遍历到一和个节点,就把该节点和新的节点树进行对比,如果有差异就放到一个对象里面
  • 遍历差异对象,根据差异的类型,根据对应对规则更新VNode

4.对React-Fiber的理解,它解决了什么问题?

Fiber 是 React 16 中全新的协调引擎(reconciliation engine),也是一种新的数据结构。

Fiber 是 React 的虚拟 DOM 的升级版,它让 React 能够实现增量渲染和更精细的任务控制。

旧架构的问题(Stack Reconciler)

在 React 16 之前,React 使用递归遍历虚拟 DOM 树来进行 diff 计算:

  • 不可中断:一旦开始渲染,就必须完成整个树的计算

  • 阻塞主线程:长时间的渲染会阻塞用户交互、动画等

  • 性能瓶颈:复杂组件树会导致页面卡顿

Fiber 要解决的问题

  1. 可中断渲染:将渲染任务拆分成小任务,可以暂停和恢复

  2. 任务优先级:区分高优先级(用户交互)和低优先级(数据更新)任务

  3. 并发渲染:为未来的并发特性打下基础

5.常用的hook

1.useState

状态管理

2.usEffect

javascript 复制代码
useEffect(() => {
  // 设置操作
  const timer = setInterval(() => {}, 1000);
  const listener = () => {};
  window.addEventListener('resize', listener);

  // 清理函数(可选)
  return () => {
    clearInterval(timer);                   // 清除定时器
    window.removeEventListener('resize', listener); // 移除监听
    console.log('清理完成!');               // 其他清理工作
  };
}, []);

useEffect 是:

  • 🔧 副作用处理器:处理组件渲染之外的操作

  • 生命周期管理器:替代 componentDidMount、componentDidUpdate、componentWillUnmount

  • 🧹 清理工具:提供清理函数避免内存泄漏

记住三个核心用法:

  1. useEffect(fn) - 每次渲染后执行

  2. useEffect(fn, []) - 只执行一次(挂载时)

  3. useEffect(fn, [a, b]) - a或b变化时执行

3.useContext

Context 的使用三步曲:

  1. 创建:const MyContext = createContext();

  2. 提供:<MyContext.Provider value={数据}>

  3. 使用:useContext(MyContext)