Skip to content

响应事件

在组件内部声明事件处理函数来响应事件:

javascript
function MyButton() {
  function handleClick() {
    alert("你点击了我!");
  }

  return <button onClick={handleClick}>点击我</button>;
}

注意onClick={handleClick} 末尾没有括号!只传递函数引用,而不是调用它。React 会在用户点击时调用你的事件处理函数。

事件绑定方式

  • 冒泡阶段onClick
  • 捕获阶段onClickCapture

事件方法

  • event.stopPropagation() - 阻止事件传播
  • event.preventDefault() - 阻止默认行为(如 a 标签跳转)
javascript
class EventDemo extends React.Component {
  childBubble(event) {
    console.log("子节点冒泡");
    event.stopPropagation();
  }

  clickLink = (event) => {
    event.preventDefault();
  };
}

事件执行顺序

React 事件系统和原生事件系统是独立的,执行顺序:

  1. React 捕获阶段
  2. React 冒泡阶段
  3. 原生捕获阶段
  4. 原生冒泡阶段

状态管理

组件使用**状态(State)**来"记忆"信息并显示它。

类组件状态

初始化状态

javascript
// 方式1:在构造函数中
constructor(props) {
  super(props);
  this.state = { number: 0 };
}

// 方式2:类属性(推荐)
state = { number: 0 };

setState 更新状态

javascript
// 对象方式
this.setState({ number: this.state.number + 1 });

// 函数方式(推荐,可基于旧状态计算新状态)
this.setState((prevState) => ({ number: prevState.number + 1 }));

// 带回调的 setState
this.setState(
  (prevState) => ({ number: prevState.number + 1 }),
  () => {
    console.log("State updated!", this.state.number);
  },
);

useState Hook

在函数组件中添加状态:

javascript
import { useState } from "react";

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

  function handleClick() {
    setCount(count + 1);
  }

  return <button onClick={handleClick}>点击了 {count} 次</button>;
}
  • count:当前状态值
  • setCount:更新状态的函数
  • useState(0):初始值为 0

函数式更新(推荐)

当新状态依赖于旧状态时,使用函数式更新:

javascript
function handleClick() {
  setCount((prevCount) => prevCount + 1);
}

setState 的异步与批量更新

React 17

  • 异步批量更新:在事件处理器、生命周期函数中,多个 setState 会被合并
  • 同步更新:在 setTimeout、Promise 等无法管理的场景中是同步的
javascript
handleClick = () => {
  this.setState({ number: this.state.number + 1 }); // 批量合并
  console.log(this.state); // 未更新
  this.setState({ number: this.state.number + 1 }); // 批量合并
  console.log(this.state); // 未更新

  setTimeout(() => {
    this.setState({ number: this.state.number + 1 }); // 同步更新
    console.log(this.state); // 已更新
  });
};

React 18

无论在什么场景,setState 都是批量的


Hooks 规则

  • 只在顶层调用:不要在循环、条件或嵌套函数中调用 Hooks
  • 只在 React 函数中调用:在 React 函数组件或自定义 Hook 中调用
javascript
// ✅ 正确
function MyComponent() {
  const [count, setCount] = useState(0);
  // ...
}

// ❌ 错误
function MyComponent() {
  if (condition) {
    const [count, setCount] = useState(0); // 不要这样做
  }
}