Skip to content

React 组件:构建复用与解耦的界面

React 是前端开发中最受欢迎的库之一,其主要特点就是其组件化的架构。React 组件允许开发者构建可重用、独立、高内聚的 UI 代码,从而提高开发速度和代码质量。

1. 什么是组件?

在 React 中,组件可以被看作是 UI 的独立、可重用的部分。它们就像 JavaScript 函数一样,接收任意的输入(称为“props”)并返回 React 元素,描述页面上的内容。

2. 函数组件与类组件

React 中有两种主要的组件类型:函数组件和类组件。

函数组件

最简单的函数组件:

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

类组件

对于需要更多功能(如状态)的组件,你可以使用 ES6 的类:

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

3. Props

Props 是父组件传递给子组件的参数,它们是只读的。

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

const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);

4. State

与 props 不同,state 是组件内部特有的,可以改变,并会导致组件重新渲染。

javascript
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  handleIncrement = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.handleIncrement}>Increment</button>
      </div>
    );
  }
}

5. 生命周期

React 类组件有多个生命周期方法,你可以在其中添加代码以运行于特定时间:

  • componentDidMount: 组件被插入到 DOM 后立即调用。
  • componentDidUpdate: 更新后立即调用。
  • componentWillUnmount: 组件从 DOM 卸载和销毁前立即调用。

6. 事件处理

在 React 中,事件处理与 DOM 事件处理略有不同:

javascript
class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isToggleOn: true };

    // 这个绑定是必要的,使`this`在回调中起作用
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

7. 用 props 和 state 传递数据

在 React 中,数据从顶部向下流动(也被称为“单向数据流”或“单向绑定”)。

我下面深入探讨 React 中的高级组件特性,如 hooks, context 和 refs。

9. Hooks

Hooks 是 React 16.8 版本中新增的特性,它允许你在不编写 class 的情况下使用 state 和其他 React 特性。

useState

这是最常用的 Hook,用于添加组件的状态。

javascript
import React, { useState } from 'react';

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

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

useEffect

useEffect 用于在组件渲染后执行副作用。

javascript
import React, { useState, useEffect } from 'react';

function App() {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetch('/api/data')
      .then(res => res.json())
      .then(data => setData(data));
  }, []);

  return (
    <div>
      {data.map(item => (
        <p key={item.id}>{item.name}</p>
      ))}
    </div>
  );
}

10. Context

React 的 Context API 允许你在组件树中更方便地传递数据,而无需通过每个层级的 props。

创建 Context

首先,你需要创建一个 Context 对象。

javascript
const ThemeContext = React.createContext('light');

使用 Context

然后,你可以使用 ProviderConsumeruseContext Hook。

javascript
import React, { useContext } from 'react';

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button theme={theme}>Themed button</button>;
}

11. Refs

Refs 提供了一种访问 DOM 节点或 React 元素的方式。

javascript
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}

或者在函数组件中使用 useRef

javascript
import React, { useRef, useEffect } from 'react';

function MyComponent() {
  const myRef = useRef(null);

  useEffect(() => {
    myRef.current.focus();
  }, []);

  return <input ref={myRef} />;
}

12. 总结

React 组件是前端开发中的一个强大工具,它不仅提供了一种优雅、高效的方式来构建用户界面,还提供了多种高级特性,如 hooks 和 context,以便在更复杂的应用程序中进行使用。

通过掌握这些基础和高级概念,我们将更好地理解 React 的工作原理,并可以构建更加强大、可维护的应用程序。