06. react 初次见面

    React 元素的事件处理和 DOM元素的很相似。但是有一点语法上的不同:

  • React事件绑定属性的命名采用驼峰式写法,而不是小写。
  • 如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM元素的写法)

    例如,传统的 HTML:

1<button onclick="activateLasers()"> 2 Activate Lasers 3</button>

    React 中稍稍有点不同:

1<button onClick={activateLasers}> 2 Activate Lasers 3</button>

    在 React 中另一个不同是你不能使用返回 false 的方式阻止默认行为。你必须明确的使用 preventDefault 。例如,传统的 HTML 中阻止链接默认打开一个新页面,你可以这样写:

1<a href="#" onclick="console.log('The link was clicked.'); return false"> 2 Click me 3</a>

    在 React,应该这样来写:

1function ActionLink() { 2 function handleClick(e) { 3 e.preventDefault(); 4 console.log('The link was clicked.'); 5 } 6 7 return ( 8 <a href="#" onClick={handleClick}> 9 Click me 10 </a> 11 ); 12}

    在这里,e 是一个合成事件。React 根据 W3C spec 来定义这些合成事件,所以你不需要担心跨浏览器的兼容性问题。查看 SyntheticEvent 参考指南来了解更多。

    使用 React 的时候通常你不需要使用 addEventListener 为一个已创建的 DOM 元素添加监听器。你仅仅需要在这个元素初始渲染的时候提供一个监听器。

    当你使用 ES6 class 语法来定义一个组件的时候,事件处理器会成为类的一个方法。例如,下面的 Toggle 组件渲染一个让用户切换开关状态的按钮:

1class Toggle extends React.Component { 2 constructor(props) { 3 super(props); 4 this.state = {isToggleOn: true}; 5 6 // This binding is necessary to make `this` work in the callback 7 this.handleClick = this.handleClick.bind(this); 8 } 9 10 handleClick() { 11 this.setState(prevState => ({ 12 isToggleOn: !prevState.isToggleOn 13 })); 14 } 15 16 render() { 17 return ( 18 <button onClick={this.handleClick}> 19 {this.state.isToggleOn ? 'ON' : 'OFF'} 20 </button> 21 ); 22 } 23} 24 25ReactDOM.render( 26 <Toggle />, 27 document.getElementById('root') 28);

    你必须谨慎对待 JSX 回调函数中的 this,类的方法默认是不会绑定 this 的。如果你忘记绑定 this.handleClick 并把它传入 onClick, 当你调用这个函数的时候 this 的值会是 undefined

    这并不是 React 的特殊行为;它是函数如何在 JavaScript 中运行的一部分。通常情况下,如果你没有在方法后面添加 () ,例如 onClick={this.handleClick},你应该为这个方法绑定 this.

    如果使用 bind 让你很困惑,这里有两种方式可以解决。如果你正在使用实验性的属性初始化器语法,你可以使用属性初始化器来正确的绑定回调函数:

1class LoggingButton extends React.Component { 2 // This syntax ensures `this` is bound within handleClick. 3 // Warning: this is *experimental* syntax. 4 handleClick = () => { 5 console.log('this is:', this); 6 } 7 8 render() { 9 return ( 10 <button onClick={this.handleClick}> 11 Click me 12 </button> 13 ); 14 } 15}

    这个语法在 Create React App 中默认开启。

    如果你没有使用属性初始化器语法,你可以在回调函数中使用 箭头函数

1class LoggingButton extends React.Component { 2 handleClick() { 3 console.log('this is:', this); 4 } 5 6 render() { 7 // This syntax ensures `this` is bound within handleClick 8 return ( 9 <button onClick={(e) => this.handleClick(e)}> 10 Click me 11 </button> 12 ); 13 } 14}

    使用这个语法有个问题就是每次 LoggingButton 渲染的时候都会创建一个不同的回调函数。在大多数情况下,这没有问题。然而如果这个回调函数作为一个属性值传入低阶组件,这些组件可能会进行额外的重新渲染。_我们通常建议在构造函数中绑定或使用属性初始化器语法_来避免这类性能问题。

1. 向事件处理程序传递参数

    通常我们会为事件处理程序传递额外的参数。例如,若是 id是一个内联 id,以下两种方式都可以向事件处理程序传递参数:

1<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button> 2<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

    上述两种方式是等价的,分别通过 arrow functions 和 Function.prototype.bind 来为特定事件类型添加事件处理程序。

    上面两个例子中,参数 e 作为 React 事件对象将会被作为第二个参数进行传递。通过箭头函数的方式,事件对象必须显式的进行传递,但是通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。

    值得注意的是,通过 bind 方式向监听函数传参,在类组件中定义的监听函数,事件对象 e 要排在所传递参数的后面,例如:

1class Popper extends React.Component{ 2 constructor(){ 3 super(); 4 this.state = {name:'Hello world!'}; 5 } 6 7 preventPop(name, e){ //事件对象e要放在最后 8 e.preventDefault(); 9 alert(name); 10 } 11 12 render(){ 13 return ( 14 <div> 15 <p>hello</p> 16 {/* Pass params via bind() method. */} 17 <a href="https://reactjs.org" onClick={this.preventPop.bind(this,this.state.name)}>Click</a> 18 </div> 19 ); 20 } 21}
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )