跳到主要内容

事件机制

合成事件

React 没有直接使用浏览器的原生事件(如 onclickonchange),而是通过 合成事件(SyntheticEvent)实现了一套跨浏览器的事件系统。

React 为什么要做合成事件呢?为了跨浏览器兼容性,统一不同浏览器的事件处理。

原理:React 将所有事件委托到根节点,通过事件冒泡统一处理。

  • e.preventDefault(); 阻止默认行为
  • e.stopPropagation(); 阻止冒泡

事件流示例:

<div onClick={() => console.log('parent')}>
<button onClick={() => console.log('child')}>child</button>
</div>

点击按钮时,child 先触发,parent 随后触发,说明是冒泡。

事件绑定

响应事件

函数组件绑定事件

function App() {
const handleClick = () => {};
return <div onClick={handleClick}>click</div>;
}

export default App;

事件传参

  1. 使用箭头函数,推荐
  2. 高阶函数
function Bar() {
const handleClick = num => {
console.log(num);
};
return <div onClick={() => handleClick(123)}>click</div>;
}

function Foo() {
const handleClick = num => {
return () => {
console.log(num);
};
};
return <div onClick={handleClick(123)}>click</div>;
}

类组件绑定事件

1、在调用的时候使用bind绑定this

class MyComponent extends React.Component {
handleSearch() {
console.log(this.props);
}

render() {
return <button onClick={this.handleSearch.bind(this)}>click</button>;
}
}

2、在构造器中使用bind绑定this

class MyComponent extends React.Component {
constructor(props) {
super(props);
this.handleSearch = this.handleSearch.bind(this);
}
handleSearch() {
console.log(this.props);
}

render() {
return <button onClick={this.handleSearch}>click</button>;
}
}

3、在箭头函数中绑定 this

class MyComponent extends React.Component {
handleSearch() {
console.log(this.props);
}

render() {
return <button onClick={() => this.handleSearch()}>click</button>;
}
}

4、public class fields 语法

class MyComponent extends React.Component {
handleSearch = () => {
console.log(this.props);
};

render() {
return <button onClick={this.handleSearch}>click</button>;
}
}

类组件推荐使用第 4 种方式绑定事件。

监听原生对象

在 useEffect 中手动绑定或解绑原生事件:

useEffect(() => {
const handleResize = () => console.log('Resized');
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);