共计 5148 个字符,预计需要花费 13 分钟才能阅读完成。
前言
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 开发鼎力的进行遍及。同时也违心与大家进行深刻的技术研究和商业单干。