关于React的事件管理指南

129 阅读6分钟

简介

事件通常代表了用户和应用程序之间的某种类型的交互--任何时候用户点击对象、在输入框中输入、拖放某些元素,等等。因此,每个事件通常需要应用程序做出某种类型的反应。每当一个重要的事件发生时,作为程序员,我们可以定义一个用于响应所发生事件的函数。这些函数被称为事件处理程序,它们是任何编程语言中事件管理的核心。事件管理是一套用于处理事件的技术。

React也不例外!在本指南中,我们将深入挖掘React中事件管理的概念。我们将看一下几种不同类型的事件,以及用于处理这些事件的机制。

DOM和React事件处理之间的差异

如果你正在使用React,你可能已经熟悉了JavaScript中的DOM事件

<!- JavaScript event ->
<button onclick="handleClick()">
    Trigger Function
</button>

这就是onclick DOM事件。当这个例子的按钮被点击时,handleClick() 函数被调用--这就是事件管理的基本原则。这个基本思想在JavaScript和React之间是共享的,但有一些细微的差别区别于它们两个。

首先,在事件命名上有一个细微的差别--React使用骆驼字母的名字,而不是JavaScript使用的小写名字。在快速浏览了前面的例子后,你会发现事件的名称是onclick ,而React的替代名称是onClick 。此外,React使用JSX(JavaScript XML),它允许我们传递一个函数作为事件处理程序(在大括号内)而不是一个字符串。

<!- React event ->
<button onClick={handleClick}>
    Trigger Function
</button>

注意我们没有在大括号内调用handleClick 函数--通过{handleClick()} 来调用它,每次元素被渲染时都会调用处理函数。我们所使用的语法确保处理函数只在事件被注册时被调用。

很多时候,你会发现自己处于这样的情况:你想在事件被注册后阻止默认行为。例如,onsubmit JavaScript事件在用户点击提交按钮后被注册。默认行为是适当地发送表单数据并重新加载网页,但我们可能需要防止重新加载网页。JavaScript在它的袖子里有一个防止默认行为的方便的技巧。

<form onsubmit="console.log('You clicked submit.'); return false">
    <button type="submit">Submit</button>
</form>

我们以通常的方式定义了处理函数,但注意到我们在处理函数的定义后面添加了return false 。这就是JavaScript开发者在处理事件时防止默认行为的方法。如果你不在这个例子中的处理函数后面加上return false ,那么在控制台有机会记录消息之前,页面就会重新加载。

**注意:**事件处理函数可以在一个JavaScript文件中定义,并在检测到事件时在HTML中调用。另外,你也可以直接在HTML代码中定义并调用处理函数(正如你在上面的例子中看到的)。

React根本不支持这一招!为了防止React中的默认行为,你必须明确地调用preventDefault

function Form() {
    function handleSubmit(e) {
        e.preventDefault();
        console.log("You clicked submit.");
    }

    return (
        <form onSubmit={handleSubmit}>
            <button type="submit">Submit</button>
        </form>
    );
}

也许不像JavaScript中的事件处理那么简单,但肯定是一种更强大的处理事件的方式。这个例子说明了事件处理在React的一个功能组件中的应用。我们只是在组件中声明了一个处理函数,并在return() 方法中调用它。

**注意:React负责处理跨浏览器的兼容性,所以你不需要担心这个问题。

在功能组件中处理事件

事件处理程序作为一个属性传递给功能组件中的元素或组件。当用户与该元素互动时,该属性会收到一个描述所发生情况的函数。

处理onClick事件

如果用户多次点击元素,onClick 事件被触发,函数被多次调用,就像任何其他事件一样。让我们看看实际情况如何,我们将创建一个按钮并调用一个函数。

const App = () => {
    const handleClick = () => {
        console.log("This function has been triggered!");
    };

    return (
        <div className="App">
            <h1>Hello World</h1>
            <button onClick={handleClick}>Trigger Function</button>
        </div>
    );
};

这将在控制台中记录出"此函数已被触发!"。

向事件中传递参数

如果我们想向被触发的函数传递参数或值,我们必须使用一个箭头函数或一个实际的函数。在我们的例子中,假设我们想向函数传递一个值,然后在控制台中记录它。

const App = () => {
    const handleClick = (name) => {
        console.log("My Name is:", name);
    };
    return (
        <div className="App">
            <h1>Hello World</h1>
            <button onClick={() => handleClick("John Doe")}>
                Trigger Function
            </button>
        </div>
    );
};

这将显示 "我的名字是。John Doe"在控制台中。我们也可以使用函数关键字来使用一个实际的函数,一切都将完美地工作。

<button onClick={function(){handleClick('John Doe')}}>Trigger Function</button>

处理onSubmit事件

当用户点击提交按钮或敲击键盘上的回车键时,我们也可以用React处理表单提交事件。这与onClick 事件的处理方式类似。

const App = () => {
    const handleSubmit = () => {
        console.log("The submit button was clicked!");
    };

    return (
        <div className="App">
            <h1>Hello World</h1>
            <form onSubmit={handleSubmit}>
                <label>Name</label>
                <input type="text" />
                <button type="submit">Submit</button>
            </form>
        </div>
    );
};

"提交按钮被点击了!"将因此而被注销。然而,由于浏览器将立即重新加载,我们将使用preventDefault() 方法来防止浏览器执行默认动作。

const handleSubmit = (e) => {
    e.preventDefault();
    console.log("The submit button was clicked!");
};

在类组件中处理事件

类组件处理事件的方式与功能组件类似,但有一些小的区别。让我们创建一个按钮,在点击时调用handleClick 函数。

class App extends React.Component {
    handleClick = () => {
        console.log("This function has been triggered!");
    };
    render() {
        return (
            <div className="App">
                <h1>Hello World</h1>
                <button onClick={this.handleClick}>Trigger Function</button>
            </div>
        );
    }
}

**注意:我们必须使用this 关键字,因为我们在App 类中,而handleClick 是该类中的一个成员函数。

向事件中传递参数

最好的做法是将处理函数声明为类组件中的一个方法。如果你想以后向渲染的组件传递参数、道具或状态,你必须在构造函数中把事件处理函数绑定到this

比方说,我们有一个状态值设置,我们想在特定的按钮被点击时进行改变,我们想使用传递的参数,我们会有这样的东西,但它会抛出一个错误

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            title: "Welcome, We are glad you are here!"
        };
    }

    handleClick = (name) => {
        console.log("This function has been triggered!", name);
        this.setState({
            title: `Hello ${name}!`
        });
    };
    render() {
        return (
            <div className="App">
                <h1>{this.state.title}</h1>
                <button onClick={this.handleClick("Joel")}>
                    Trigger Function
                </button>
            </div>
        );
    }
}

为了解决这个问题,我们要么使用箭头函数或者 Function.prototype.bind]来绑定this 关键字。

<button onClick={() => this.handleClick("John Doe")}>Trigger Function</button>
<button onClick={this.handleClick.bind(this, "John Doe")}>Trigger Function</button>

处理onSubmit事件

我们也可以用类组件来处理所有类型的事件,只要我们在声明方法时使用this 关键字而不是函数。

class App extends React.Component {
    handleSubmit = (e) => {
        e.preventDefault();
        console.log("The submit button was clicked!");
    };
    render() {
        return (
            <div className="App">
                <h1>Hello World</h1>
                <form onSubmit={this.handleSubmit}>
                    <label>Name</label>
                    <input type="text" />
                    <button type="submit">Submit</button>
                </form>
            </div>
        );
    }
}

结语

我们在本指南中看到,React事件与JavaScript事件非常相似,只是在语法和传播行为上有一些区别。我们还学习了功能组件和类组件中使用的事件处理程序的区别,类组件需要将处理程序绑定到this 。在React中可以处理的事件还有很多,但无论在功能组件还是类组件中,它们的功能都与onClick 方法相同。