react函数组件、类组件、纯组件、受控/非受控组件

一、函数组件 vs 类组件

1️⃣ 函数组件(Function Component)

本质:就是一个函数,接收 props,返回 JSX

javascript 复制代码
function MyComponent(props) {
  return <div>{props.title}</div>;
}

👉 现在主流写法(配合 Hooks)

特点:

  • 更简洁
  • 使用 useStateuseEffect 等 Hooks 管理状态和副作用
  • 没有 this
javascript 复制代码
import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>
      {count}
    </button>
  );
}

2️⃣ 类组件(Class Component)

本质:继承 React.Component 的类

scala 复制代码
class MyComponent extends React.Component {
  render() {
    return <div>{this.props.title}</div>;
  }
}

带状态写法:

scala 复制代码
class Counter extends React.Component {
  state = { count: 0 };

  render() {
    return (
      <button onClick={() => this.setState({ count: this.state.count + 1 })}>
        {this.state.count}
      </button>
    );
  }
}

特点:

  • 有生命周期(componentDidMount 等)
  • 使用 this
  • 写法相对冗长

✅ 总结

对比 函数组件 类组件
写法 简洁 冗长
状态 Hooks this.state
生命周期 useEffect 生命周期方法
推荐 ✅ 主流 ❌ 已逐渐淘汰

👉 现在基本都用:函数组件 + Hooks


二、普通组件 vs 纯组件(PureComponent)

1️⃣ 普通组件

默认:父组件更新 → 子组件也会重新 render


2️⃣ 纯组件(PureComponent)

类组件写法:

scala 复制代码
class MyComponent extends React.PureComponent {
  render() {
    return <div>{this.props.name}</div>;
  }
}

👉 自动做 浅比较(shallow compare)

只有 props/state 变化才重新渲染


👉 函数组件对应写法:React.memo

javascript 复制代码
const MyComponent = React.memo(function ({ name }) {
  return <div>{name}</div>;
});

⚠️ 注意点

浅比较意味着:

ini 复制代码
const obj = { a: 1 };

// ❌ 每次都是新对象,会触发更新
<MyComponent data={{ a: 1 }} />

// ✅ 推荐
const data = useMemo(() => ({ a: 1 }), []);

✅ 总结

类型 作用
PureComponent 类组件性能优化
React.memo 函数组件性能优化

三、受控组件 vs 非受控组件

👉 这个是表单相关最重要的概念


1️⃣ 受控组件(Controlled Component)

👉 数据由 React 控制(state)

javascript 复制代码
function Input() {
  const [value, setValue] = useState("");

  return (
    <input
      value={value}
      onChange={(e) => setValue(e.target.value)}
    />
  );
}

特点:

  • 数据来源:React state
  • 输入变化 → 更新 state → UI 更新
  • 单向数据流

👉 推荐使用 ✅


2️⃣ 非受控组件(Uncontrolled Component)

👉 数据由 DOM 自己管理

javascript 复制代码
import { useRef } from "react";

function Input() {
  const inputRef = useRef();

  const handleClick = () => {
    console.log(inputRef.current.value);
  };

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>获取值</button>
    </>
  );
}

特点:

  • 使用 ref 获取值
  • 类似原生 JS 操作 DOM

✅ 总结

对比 受控组件 非受控组件
数据来源 React state DOM
可控性
推荐 ⚠️ 少用

四、一句话理解(面试版)

👉 你可以这样说:

  • 函数组件 vs 类组件:函数组件更简洁,配合 Hooks 替代类组件,是当前主流
  • 纯组件:通过浅比较 props/state 来减少不必要渲染(React.memo / PureComponent)
  • 受控组件:表单数据由 React state 管理
  • 非受控组件:表单数据由 DOM 管理,通过 ref 获取

五、给你一个实际开发建议(结合你现在做的项目)

你现在做 React + Ant Design:

👉 推荐组合:

  • 全部用 函数组件
  • 状态管理:Hooks(useState / useReducer)
  • 性能优化:React.memo + useMemo
  • 表单:优先用 受控组件(或 AntD Form 内部已封装)
相关推荐
kyriewen34 分钟前
面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了
前端·javascript·面试
IT_陈寒1 小时前
Vite热更新失效?你可能漏了这个配置
前端·人工智能·后端
Revolution611 小时前
React 组件重新渲染时,到底重新执行了什么
前端·react.js·面试
林焱_RPAAI2 小时前
影刀RPA技术深度:CSS选择器高级实战指南——伪类属性选择器与性能对比完全解析
vue.js·react.js
用户2181697049303 小时前
Flutter(四)Dart语法 空安全 运算符 流程控制
前端
许彰午3 小时前
政务督办的分合模式:主办协办的并发审批
前端·javascript·政务
用户69371750013843 小时前
AI时代,程序员该往哪走?
前端·后端
ttwuai3 小时前
GoFrame 后台日志清空失败:无 WHERE 删除为什么被拦住
前端·golang
易筋紫容3 小时前
创建型模式:对象的诞生艺术
开发语言·前端·javascript
半句唐诗4 小时前
我是如何通过 Access Token 成功发布第一个 npm 包的
前端·npm·node.js