react:组件基础

第五章:组件基础

函数组件是定义 React 组件最简单的方式。它是一个接收 props 对象并返回 React 元素的 JavaScript 函数。

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

特点

  • 简洁:纯函数,没有生命周期方法和 this
  • 无状态(Hooks 之前):只能接收 props,不能管理自己的 state
  • 性能:没有实例化开销,渲染更快

使用箭头函数

const Welcome = (props) => {
  return <h1>Hello, {props.name}</h1>;
};
 
// 简写形式(隐式返回)
const Welcome = (props) => <h1>Hello, {props.name}</h1>;
 
// 解构 props
const Welcome = ({ name }) => <h1>Hello, {name}</h1>;

类组件使用 ES6 的 class 语法定义,继承自 React.Component。

import React from 'react';
 
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

特点

  • 可以使用 state 管理组件内部状态
  • 可以使用生命周期方法
  • 有 this 关键字
  • 需要 render() 方法返回 JSX

组件可以相互组合,形成组件树。

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
 
function App() {
  return (
    <div>
      <Welcome name="张三" />
      <Welcome name="李四" />
      <Welcome name="王五" />
    </div>
  );
}

提取组件

当 UI 的一部分被多次使用,或者自身足够复杂时,可以将其提取为独立的组件。

// 原始代码
function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <img className="Avatar"
          src={props.author.avatarUrl}
          alt={props.author.name}
        />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}
 
// 提取 Avatar 组件
function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  );
}
 
// 提取 UserInfo 组件
function UserInfo(props) {
  return (
    <div className="UserInfo">
      <Avatar user={props.user} />
      <div className="UserInfo-name">
        {props.user.name}
      </div>
    </div>
  );
}
 
// 重构后的 Comment 组件
function Comment(props) {
  return (
    <div className="Comment">
      <UserInfo user={props.author} />
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

Props(properties 的缩写)是组件之间传递数据的方式。

传递 props

function App() {
  return <User name="张三" age={25} isAdmin={true} />;
}

接收 props

function User(props) {
  return (
    <div>
      <p>姓名:{props.name}</p>
      <p>年龄:{props.age}</p>
      <p>{props.isAdmin ? '管理员' : '普通用户'}</p>
    </div>
  );
}
 
// 使用解构
function User({ name, age, isAdmin }) {
  return (
    <div>
      <p>姓名:{name}</p>
      <p>年龄:{age}</p>
      <p>{isAdmin ? '管理员' : '普通用户'}</p>
    </div>
  );
}

Props 的只读性

组件不能修改自己的 props。props 对于组件来说是只读的。

// 错误!props 是只读的
function Welcome(props) {
  props.name = 'Hello'; // 错误!
  return <h1>{props.name}</h1>;
}

为 props 设置默认值:

函数组件

function Button({ text = '点击', type = 'button' }) {
  return <button type={type}>{text}</button>;
}
 
// 或者
function Button(props) {
  const { text = '点击', type = 'button' } = props;
  return <button type={type}>{text}</button>;
}

类组件

class Button extends React.Component {
  static defaultProps = {
    text: '点击',
    type: 'button'
  };
 
  render() {
    return <button type={this.props.type}>{this.props.text}</button>;
  }
}
 
// 或者在组件外部
Button.defaultProps = {
  text: '点击',
  type: 'button'
};

PropTypes 用于运行时类型检查。

安装:

npm install prop-types

使用:

import PropTypes from 'prop-types';
 
function User({ name, age, email }) {
  return (
    <div>
      <p>{name}</p>
      <p>{age}</p>
      <p>{email}</p>
    </div>
  );
}
 
User.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number,
  email: PropTypes.string,
  isAdmin: PropTypes.bool,
  hobbies: PropTypes.array,
  address: PropTypes.object,
  onClick: PropTypes.func,
  element: PropTypes.element,
  nodes: PropTypes.node,
  user: PropTypes.instanceOf(User),
  shape: PropTypes.shape({
    color: PropTypes.string,
    fontSize: PropTypes.number
  }),
  oneOf: PropTypes.oneOf(['News', 'Photos']),
  oneOfType: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number
  ]),
  arrayOf: PropTypes.arrayOf(PropTypes.number),
  objectOf: PropTypes.objectOf(PropTypes.number),
  any: PropTypes.any
};
 
User.defaultProps = {
  age: 18
};

TypeScript 替代方案

如果使用 TypeScript,可以使用接口定义 props 类型,获得编译时类型检查。

children 是一个特殊的 prop,用于在组件标签之间传递内容。

function Card({ title, children }) {
  return (
    <div className="card">
      <div className="card-header">{title}</div>
      <div className="card-body">{children}</div>
    </div>
  );
}
 
// 使用
function App() {
  return (
    <Card title="欢迎使用">
      <p>这是卡片的内容</p>
      <button>了解更多</button>
    </Card>
  );
}

children 的类型

  • React 元素
  • 字符串或数字
  • 数组(Fragment)
  • 函数(render props)
  • null、undefined、boolean(不渲染)

render props 是一种在 React 组件之间使用一个值为函数的 prop 共享代码的技术。

class MouseTracker extends React.Component {
  state = { x: 0, y: 0 };
 
  handleMouseMove = (event) => {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  };
 
  render() {
    return (
      <div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
        {this.props.render(this.state)}
      </div>
    );
  }
}
 
// 使用
function App() {
  return (
    <MouseTracker render={({ x, y }) => (
      <p>鼠标位置:({x}, {y})</p>
    )} />
  );
}

高阶组件是一个函数,接收一个组件并返回一个新的组件。

function withLogger(WrappedComponent) {
  return class extends React.Component {
    componentDidMount() {
      console.log('Component mounted:', WrappedComponent.name);
    }
 
    render() {
      return <WrappedComponent {...this.props} />;
    }
  };
}
 
// 使用
const EnhancedComponent = withLogger(MyComponent);

常见的 HOC 用途

  • 权限控制
  • 日志记录
  • 数据获取
  • 样式增强

按功能组织

src/
├── components/          # 可复用的 UI 组件
│   ├── Button/
│   │   ├── Button.js
│   │   ├── Button.css
│   │   └── Button.test.js
│   └── Card/
├── features/            # 功能模块
│   ├── User/
│   │   ├── UserList.js
│   │   ├── UserForm.js
│   │   └── userSlice.js
│   └── Product/
├── hooks/               # 自定义 Hooks
├── utils/               # 工具函数
├── api/                 # API 调用
└── App.js

按类型组织

src/
├── components/          # 所有组件
├── containers/          # 容器组件
├── actions/             # Redux actions
├── reducers/            # Redux reducers
├── utils/               # 工具函数
└── App.js

本章介绍了组件的基础知识:

  • 函数组件和类组件
  • 组件组合
  • Props 传递和使用
  • 默认 Props 和类型检查
  • children 和 render props
  • 高阶组件

组件是 React 的核心概念,理解组件的各种用法是掌握 React 的关键。

该主题尚不存在

您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。

  • react/组件基础.txt
  • 最后更改: 2026/03/13 15:50
  • 张叶安