另一篇总结:react 中的事件绑定 。 2019-05-16 更新
javascript
建议:在了解 js 的 this 取值后食用更佳。html
html 中的绑定事件的写法:
java
<button onclick="activateLasers()"> // onClick = "xxxx()"
激活按钮
</button>
react 中的写法:react
<button onClick={activateLasers}> // onclick = { xxxx }
激活按钮
</button>
在 React 中另外一个不一样是你不能使用返回 false 的方式阻止默认行为, 必须明确的使用 preventDefault。ide
例如,一般咱们在 HTML 中阻止连接默认打开一个新页面,能够这样写:函数
<a href="#" onclick="console.log('点击连接'); return false"> // return false 点我 </a>
可是,在 react 中,阻止默认行为必须得用下面的方式:this
function ActionLink() {
function handleClick(e) {
e.preventDefault(); // preventDefault()
console.log('连接被点击');
}
return (
<a href="#" onClick={handleClick}>
点我
</a>
);
}
一样,使用 React 的时候一般不须要使用 addEventListener 为一个已建立的 DOM 元素添加监听器。只须要在这个元素初始渲染的时候提供一个监听器。spa
首先一个例子:code
class Toggle extends React.Component { constructor(props) { super(props); this.state = {isToggleOn: true}; // 这边绑定是必要的,这样 `this` 才能在回调函数中使用
// 这是其中的一种写法 this.handleClick = this.handleClick.bind(this); } handleClick() { this.setState(prevState => ({ // prevState 会在后面关于 setState 中详细介绍 isToggleOn: !prevState.isToggleOn })); } render() { return ( <button onClick={this.handleClick}> {this.state.isToggleOn ? 'ON' : 'OFF'} </button> ); } } ReactDOM.render( <Toggle />, document.getElementById('example') );
为何须要这样写?htm
个人见解是和 this、 bind() 以及 函数的执行符号 有关。函数执行的符号是 "()"。
1 1.为何在以前的组件案例(入坑笔记(二)的 Clock 组件)中的 tick 方法不须要绑定?
你必须谨慎对待 JSX 回调函数中的 this,类的方法默认是不会绑定 this 的。若是你忘记绑定 this.handleClick 并把它传入 onClick, 当你调用这个函数的时候 this 的值会是 undefined。
这并非 React 的特殊行为;它是函数如何在 JavaScript 中运行的一部分。一般状况下,若是你没有在方法后面添加 () ,例如 onClick={this.handleClick},你应该为这个方法绑定 this。
函数绑定的其余两种方法:
1.使用 ES6 的箭头函数来定义组件中的函数(属性初始化语法):
class LoggingButton extends React.Component { // 这个语法确保了 `this` 绑定在 handleClick 中 handleClick = () => { console.log('this is:', this); } render() { return ( <button onClick={this.handleClick}> Click me </button> ); } }
2.render 函数中使用回调函数(不建议使用):
class LoggingButton extends React.Component { handleClick() { console.log('this is:', this); } render() { // 这个语法确保了 `this` 绑定在 handleClick 中 return ( <button onClick={(e) => this.handleClick(e)}> // 这边其实是执行了一个回调函数,在回调函数中执行 handleClick 方法 Click me </button> ); } }
两种方式,等价:
1 <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button> // 回调形式传参 2 <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button> // bind() 形式传参
值得注意的是,经过 bind 方式向监听函数传参,在类组件中定义的监听函数,事件对象 e 要排在所传递参数的后面,例如:
class Popper extends React.Component{ constructor(){ super(); this.state = {name:'Hello world!'}; } preventPop(name, e){ //事件对象e要放在最后 e.preventDefault(); alert(name); } render(){ return ( <div> <p>hello</p> {/* 经过 bind() 方法传递参数。 */} <a href="https://reactjs.org" onClick={this.preventPop.bind(this,this.state.name)}>Click</a> </div> ); } }