react事件与DOM事件大致相同,但是有一下几点语法差异
1 事件命名采用camelCase 而不是lowercase
2 在JSX中通过传递一个方法用{}括起来(JSX在遇到{},理解为括号内是js表达式而去执行他),而不是使用一个字符串的方式表示
<button οnclick="activateLasers()">
Activate Lasers
</button>
<button onClick={activateLasers}> // 一个组件的函数
Activate Lasers
</button>
还有一个不同点是, react的事件处理函数不能通过返回false来阻止浏览器默认行为
<a href="#" οnclick="console.log('The link was clicked.'); return false">
Click me
</a>
function ActionLink() {
function handleClick(e) { // e是一个合成事件,非原生,react根据w3c生成
e.preventDefault(); //阻止方式
console.log('The link was clicked.');
}
return (
<a href="#" onClick={handleClick}>
Click me
</a>
);
}
对于监听器的绑定,我们不需要在浏览器渲染出DOM元素后,通过findElementByid之类的方式获得元素的引用来手动绑定事件,这比较原始的方式广泛应用于原生接口与jquery上,我们只需要在render上返回的react element上(一种描述想要渲染成那种界面的对象)绑定事件就可以了 ,实例如下
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
/* 之所以绑定执行环境为this,因为handleClick被触发时this不再指向组件实例,所以需要手动指定,这其实是js的缺陷,比如
class A{
constructor( ) {
this.a=5
}
say(){
console.log(this.a) //5
}
}
let a=new A()
let outSay=a.say
outSay() //产生异常,因为this可能是undefined
须知这不是react的过失,而是js函数的运行原理导致的,当然除了上面使用apply的方式 你也可以通过别的方式去解决这个问题,比如声明handleClick时使用es6的箭头函数 ,或者在 onClick上使用 onClick={()=>{handleClick}}但是在onclick中使用箭头函数有缺点,这种方式会在组件每次渲染创建一个全新的回调函数实例,正常情况下这没问题,单当这种回调传递给子组件时导致子组件重新进行不必要的渲染,因此相对之前两种不推荐使用,除非你需要动态传入额外的参数
*/
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return ( //react element
<button onClick={this.handleClick}> // 非字符串
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
对于参数的传递,两种等价方式,但是第二种会自动传递e,因为bind本质上依然返回的是一个普通函数,后续会被调用传递参数
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
有关渲染
你可以在render中 调用return之前,通过传统js中的if等语句进行筛选,如果return结构复杂可以抽象成一个变量来表达一部分react element,然后吧这个变量交给render 的renturn渲染.
对于return中可以使用 逻辑运算符和三元运算符 进行条件判断 筛选哪个react element渲染,另外,如果return返回null,界面不会显示,但是组件实例的生命周期依然会被触发,相当于组件只是没有被渲染在界面上,但是在内存中是存在的.
let el=(<div><p>这是一个文本</p></div>)
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 && // 逻辑运算符用作react element上
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
{el} //变量方式
The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in. //三元运算符
</div>
render() { const isLoggedIn = this.state.isLoggedIn;
return ( <div> The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in. </div> );}
render() {
const isLoggedIn = this.state.isLoggedIn;
return ( <div> {isLoggedIn ? ( <LogoutButton onClick={this.handleLogoutClick} /> ) : ( <LoginButton onClick={this.handleLoginClick} /> )} </div> );}
以上三种都应该包裹在 {}上, 让react解释的时候能够知道{}内的语句时js表达式. 猜想react是根据{来判断执行js,<认为是标签的逻辑