添加事件
React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同:
- React 事件的命名采用小驼峰式(camelCase),而不是纯小写。
- 使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。
class HelloWorld extends React.Component {
say(){
console.log('say...');
}
render(){
return (
<div>
<h2 onClick={this.say}>hello,world!</h2>
</div>
)
}
}
// 通过调用React自身方法render可以得到当前组件的实例对象,并渲染到页面容器.
ReactDOM.render(<HelloWorld />,document.getElementById('root'));
event对象
在这里,e 是一个合成事件。React 根据 W3C 规范来定义这些合成事件,所以你不需要担心跨浏览器的兼容性问题。React 事件与原生事件不完全相同。如果想了解更多,请查看 SyntheticEvent 参考指南。class HelloWorld extends React.Component {
say(e){
console.log('say...');
console.log(e.target);
}
render(){
return (
<div>
<h2 onClick={this.say}>hello,world!</h2>
</div>
)
}
}
// 通过调用React自身方法render可以得到当前组件的实例对象,并渲染到页面容器.
ReactDOM.render(<HelloWorld />,document.getElementById('root'));
向事件传参
这里我们必须通过箭头函数返回一个新的函数来实现onClick传参的目的.class HelloWorld extends React.Component {
say(e){
console.log('say...');
console.log(e.target);
}
jumpTo(e){
// 可以通过e阻止默认事件
e.preventDefault();
console.log(e.target);
}
deleteById(id,e){
console.log(e);
console.log('删除: '+id);
}
render(){
return (
<div>
<h2 onClick={this.say}>hello,world!</h2>
<a href="https://bufanui.com" onClick={this.jumpTo}>不凡官网</a>
<p onClick={e=> this.deleteById(1,e)}>id:1的数据</p>
</div>
)
}
}
// 通过调用React自身方法render可以得到当前组件的实例对象,并渲染到页面容器.
ReactDOM.render(<HelloWorld />,document.getElementById('root'));
关于this
你必须谨慎对待 JSX 回调函数中的this
,在 JavaScript 中,class 的方法默认不会绑定this
。如果你忘记绑定this.handleClick
并把它传入了onClick
,当你调用这个函数的时候this
的值为undefined
。
这并不是 React 特有的行为;这其实与 JavaScript 函数工作原理有关。通常情况下,如果你没有在方法后面添加()
,例如onClick={this.handleClick}
,你应该为这个方法绑定this
。—原文
例子1:
实际上报错,打印this是 undefined
.
class HelloWorld extends React.Component {
constructor(props){
super(props);
this.state = ({
toggle: true
})
}
toggleBtn(){
console.log('this',this);
// 注意: 这里必须返回一个state对象
this.setState((state)=>({
toggle: !state.toggle
}))
}
render(){
return (
<div>
<button onClick={this.toggleBtn}>开关/{this.state.toggle?'关闭':'开启'}</button>
</div>
)
}
}
// 通过调用React自身方法render可以得到当前组件的实例对象,并渲染到页面容器.
ReactDOM.render(<HelloWorld />,document.getElementById('root'));
我们稍作修改, 在构造方法通过bind重新绑定this:
这样我们实现了效果,而且发现在__proto__
上和构造函数中都存在 toggleBtn()
.
class HelloWorld extends React.Component {
constructor(props){
super(props);
this.state = ({
toggle: true
})
// 在构造函数里通过bind重新绑定this
this.toggleBtn = this.toggleBtn.bind(this);
}
toggleBtn(){
console.log('this',this);
// 注意: 这里必须返回一个state对象
this.setState((state)=>({
toggle: !state.toggle
}))
}
render(){
return (
<div>
<button onClick={this.toggleBtn}>开关/{this.state.toggle?'关闭':'开启'}</button>
</div>
)
}
}
// 通过调用React自身方法render可以得到当前组件的实例对象,并渲染到页面容器.
ReactDOM.render(<HelloWorld />,document.getElementById('root'));
例子2:
我们通过箭头函数声明toggleBtn()
, 结果正常,,因为箭头函数会继承父类的this,所以这里的this指向实例对象.
从打印的结果我们可以看到, 箭头函数声明的方法,可以等同于在构造函数中通过this声明.
class HelloWorld extends React.Component {
constructor(props){
super(props);
this.state = ({
toggle: true
})
}
// 这里改成箭头函数,由于箭头函数会继承父类的this,所以这里的this指向实例对象.
toggleBtn=()=>{
console.log('this',this);
// 注意: 这里必须返回一个state对象
this.setState((state)=>({
toggle: !state.toggle
}))
}
render(){
return (
<div>
<button onClick={this.toggleBtn}>开关/{this.state.toggle?'关闭':'开启'}</button>
</div>
)
}
}
// 通过调用React自身方法render可以得到当前组件的实例对象,并渲染到页面容器.
ReactDOM.render(<HelloWorld />,document.getElementById('root'));