前言

React框架是一个组件化的框架,为了适宜大型项目的开发,React将我的项目宰割成一个个的组件,并频繁地在组件之间传递数据。能够说要想学好React框架的应用,须要可能灵便地操作组件。本文重点介绍React组件的书写形式,并给出组件中数据与事件的解决规定。

留神:React 16.x之前的版本中,创立组件能够应用React.createClass()办法来实现,然而从React 16版本开始,该办法彻底被废除,开始全面应用ES6中的class关键字来创立组件。在学习过程中,大家就不要再尝试React.createClass()办法了。


一、应用ES6的class关键字创立组件

React应用ES6的class关键字创立组件的语法格局如下所示。

class 组件名 extends React.Component{  render(){    return (       //JSX元素    )  }} 

上述格局在书写时有以下格局要求:

  • 组件名的首字母必须大写。
  • 必须具备render()函数。
例1:创立一个名为App的组件,该组件显示一个h2题目和具备3个列表项的无序列表。
class App extends React.Component{  render(){    return (      <React.Fragment>        <h2>前端开发的三大框架</h2>        <ul>          <li>React</li>          <li>Vue.js</li>          <li>Angular</li>        </ul>      </React.Fragment>    )  }}ReactDOM.render(  <App></App>,  document.querySelector("#app")) 

从上述代码中能够看出,组件名App能够呈现在ReactDOM.render()函数的第一个参数中,既能够是标记对的格局(<App></App>),也能够是单标签的格局(<App />)。

能够看出,有两个React属性在组件中十分罕用:

  • React.Component:所有的自定义组件都继承React.Component。
  • React.Fragment:作为自定义组件的惟一根节点,并在DOM构造中不渲染。

为了简化上述两个属性的调用,咱们能够应用ES6对象解构的格局在我的项目结尾对其进行申明:

const {Component,Fragment} = React; 

咱们用这种办法再率领大家创立一个组件。

例2:创立一个名为App的组件,该组件遍历数组造成5个超级链接。
const {Component,Fragment}=React;let linkText=["百度","腾讯","新浪","网易","谷歌"];let linkUrl=[  "https://www.baidu.com",  "https://www.qq.com",  "https://www.sina.com.cn",  "https://www.163.com",  "https://www.google.com"];class App extends React.Component{  render(){    return (      <React.Fragment>        {          linkText.map((item,index)=>{            return <a href={linkUrl[index]} key={index}>{item}</a>          })        }      </React.Fragment>    )  }}ReactDOM.render(  <App></App>,  document.querySelector("#app")); 

二、为组件设置状态区

依据ES6语法规定,应用class定义的React组件实质上是一个类,ES6容许在类的外部为类设置一个构造函数,在这个构造函数外部能够为整个React组件设置状态区(state)。学习过Vue.js框架的小伙伴们能够将其了解为Vue实例的数据区(即data局部)。

语法格局如下所示。

class 组件名 extends React.Component{  constructor(props){    super(props);    this.state={      //申明状态区数据    }  }} 
例3:组件Student的状态区有两个数据,题目title和学生信息info,利用状态区的数据在页面中生成展现学生信息的表格。
const {Component,Fragment}=React;class Student extends Component{  constructor(props){    super(props);    this.state={      title:'小海前端2059期学员名单',      info:[        {name:'张三', sex:'男', age:24, phone:'159xxxxxxxx'},        {name:'李四', sex:'女', age:22, phone:'139xxxxxxxx'},        {name:'王五', sex:'男', age:25, phone:'157xxxxxxxx'}      ]    }  }  render(){    return (      <Fragment>        <h2>{this.state.title}</h2> <hr/>        <table>          <thead>            <tr>              <th>姓名</th>  <th>性别</th>  <th>年龄</th>  <th>联系电话</th>            </tr>          </thead>          <tbody>            {              this.state.info.map((stud,index)=>{                return (                  <tr key={index}>                    <td>{stud.name}</td>                    <td>{stud.sex}</td>                    <td>{stud.age}</td>                    <td>{stud.phone}</td>                  <tr>                )              })            }          </tbody>        </table>      </Fragment>    )  }}ReactDOM.render(    <Student></Student>,document.querySelector("#app")); 

从上述代码中能够看出,在JSX语法结构中援用state区中的数据要应用 this.state 的格局来实现。

大家思考一个问题:这里的this指向什么呢?

class Student extends Component {  constructor(props){    super(props);    this.state={      //定义state区数据    }  }  render(){    console.log(this);    return (      //JSX语法结构    );  }} 

上述代码在render()函数中利用console.log()构造将this的内容输入到控制台中,最终的输入后果如下图所示。

从这个图中能够看出,组件中的this关键字总是指向这个组件自身,并且能够通过this.state调用组件状态区中的数据。

那么如何批改组件state区中的数据呢?这里须要用到this.setState()办法来实现,格局如下所示。

this.setState({  数据名:取值}) 

让咱们先为大家解说如何为组件中的元素绑定事件,而后在事件触发时再来批改state区中的数据。

三、为组件中的元素绑定事件

在React中,个别采纳元素属性的形式来为其绑定事件。事件类型名采纳on-结尾,前面的事件单词采纳首字母大写的模式来书写。

  • 单击事件:onClick
  • 鼠标通过事件onMouseOver
  • 鼠标来到事件onMouseOut
  • 取得焦点事件:onFocus
  • 开释焦点事件:onBlur
例4:创立Exam组件。页面中有一个按钮,单击按钮扭转state数据区中名为frame的数据取值。
const {Component,Fragment}=React;class Exam extends Component{  constructor(props){    super(props);    this.state={      frame:'Vue.js'    }  }  changeData(){    this.setState({      frame:'React'    })  }  render(){    return (      <Fragment>        <button onClick={this.changeData.bind(this)}>扭转数据</button>        <p>你好,{this.state.frame}</p>      </Fragment>    )  }}ReactDOM.render(  <Exam></Exam>,  document.querySelector("#app")); 

大家仔细观察为button按钮绑定单击事件的句子:

<button onClick={this.changeData.bind(this)}>扭转数据</button> 

该句的实质是定义了一个名为changeData()的函数,让按钮的单击事件触发时执行这个函数。然而,在函数中this关键字就不指向组件自身了。为了让函数外部的this也只想组件自身,必须在JSX语法结构中调用函数时应用bind(this)来保障this关键字在函数中的指向。

如果在事件函数外部应用不到this关键字,那么在调用函数时就能够不应用bind(this)了。

例5:创立组件Box。在页面中有一个矩形容器,当鼠标通过时让其扭转背景色彩(#ff5857),鼠标来到时复原原有的背景色彩(#3385ff)。
const {Component,Fragment}=React;class Box extends Component{  constructor(props){    super(props);    this.state={      bgc:'#ff5857'    }  }  mouseOver(){    this.setState({      bgc:'#3385ff'    })  }  mouseOut(){    this.setState({      bgc:'#ff5857'    })  }  render(){    return (      <Fragment>        <div className="box"             style={{backgroundColor:this.state.bgc}}             onMouseOver={this.mouseOver.bind(this)}             onMouseOut={this.mouseOut.bind(this)}>        </div>      </Fragment>    )  }}ReactDOM.render(    <Box></Box>,    document.querySelector("#app")); 

上述代码中的div,类名box负责设置容器的宽度和高度,style属性负责设置背景色彩,同时背景色彩应用了一个state区中名为bgc的数据来设置。当鼠标通过这个容器时利用this.setState()办法扭转bgc的取值为#3385ff;当鼠标来到这个容器时利用this.setState()办法扭转bgc的取值为#ff5857。

四、确保组件办法中的this指向组件自身

后面的例子咱们是采纳bind(this)的办法来保障组件中办法外部的this指向组件自身的。本大节为大家总结其余的实现办法。

1、调用办法时应用bind(this)来扭转办法外部this的指向。

<button onClick={this.btnClick.bind(this)}>提交</button> 

2、在构造函数中注册办法。

也能够在构造函数中将这个办法利用bind(this)注册一遍,这样在调用时就不须要在扭转this的指向了。

constructor(props){   super(props);   this.state={ //定义state区数据 };   this.btnClick=this.btnClick.bind(this);      //在构造函数中从新注册办法}<button onClick={this.btnClick()}>提交</button> 

3、在调用办法时应用箭头函数。

也能够在调用办法是间接应用箭头函数,这样也能够解决办法外部this的指向问题。

<button onClick={()=>this.btnClick()}>提交</button> 

上述三种办法都能够实现对事件函数的调用,同学们能够在例3或例4的根底上扭转调用办法的形式,自行演示上述办法的可行性。


总结

本文是React系列教程的第三篇文章,次要为大家解说了React组件的书写形式。同时还解说了组件状态区的应用、为组件元素绑定事件等。今天会为大家零碎的解说React组件数据之间的传递。

对于作者

小海前端,具备18年Web我的项目开发和前后台培训教训,在前端畛域著有较为零碎的培训教材,对Vue.js、微信小程序开发、uniApp、React等全栈开发畛域都有较为深的造诣。入住Segmentfault,心愿可能更多的结识Web开发畛域的同仁,将Web开发鼎力的进行遍及。同时也违心与大家进行深刻的技术研究和商业单干。