一.react组件简绍
组件分类:
-
基础组件:指
input
、button
这种基础标签,以及antd封装过的通用UI组件 -
业务组件:由基础组件组合成的业务抽象化UI。例如公司部门信息的下拉框
-
区块组件:由基础组件组件和业务组件组合成的UI块
-
页面组件:展示给用户的最终页面,一般就是对应一个路由规则
具体组件使用可以去这个博客看看:React学习:组件(Components)_若水弹丸之地-CSDN博客
二.react组件的两种创建方式
- 使用 JS 中的
函数
创建组件 - 使用 JS 中的
class
创建组件
具体代码示例如下:
import React from 'react'
import ReactDOM from 'react-dom'
const title = <h1>react的两种组件</h1>
// 定义一个函数式组件
const Com1 = () => {
return <div>第一个函数式组件</div>
}
// 定义一个类组件
class Com2 extends React.Component {
render () {
return <div>第一个类组件</div>
}
}
const content = (
<div>
{title}
{<Com1 />}
<hr />
{<Com2 />}
</div>
)
ReactDOM.render(content, document.getElementById('root'))
通过上面代码我们可以对比出类组件比较繁琐,函数式组件比较简便,下面我们分别来学习一下函数式和class类创建组件.
函数式组件-使用函数创建组件
在使用之前我们先了解一下什么叫函数组件: 使用JS的函数(或者箭头函数)创建的组件
使用函数组件注意事项:
-
约定1:函数名首字符大写
必须以大写字母开头**,React 据此区分
组件
和普通的 HTML
-
约定2:必须有返回值
表示该组件的 UI 结构;如果不需要渲染任何内容,则返回 nul
代码示列:
import reactDom from 'react-dom'
// 函数式组件
const Hello = () => {
return <h1>Hello</h1>
}
const app = (
<div>
APP
<Hello />
</div>)
reactDom.render(app, document.getElementById('root'))
类组件-用class创建组件
定义: 使用 ES6 的 class 创建的组件,叫做类(class)组件
在使用类组件的注意和要求:
-
类名必须以大写字母开头
-
extends是一个关键字,用来实现类之间的继承。类组件应该继承 React.Component 父类,从而使用父类中提供的方法或属性。
-
类组件必须提供 render 方法,render 方法必须有返回值,表示该组件的 UI 结构。render会在组件创建时执行一次
示列代码:
import reactDom from 'react-dom'
import React from 'react'
//类组件
class Hello extends React.Component {
render () {
return <h1>Hello</h1>
}
}
const app = (
<div>
APP
<Hello />
</div>
)
reactDom.render(app, document.getElementById('root'))
以上两种的组件使用方式一致 ,都可以使用单标签和双标签.
三.有状态组件和无状态组件
在学习状态组件之前我们先来了解一下什么是状态.
状态是用来描述事物在某一时刻的形态的数据,一般称为state
特点及作用:
- 状态能被改变,改变了之后视图会有对应的变化
- 保存数据
- 为后续更新视图打下基础
有状态组件:能定义state的组件。类组件就是有状态组件。
无状态组件:不能定义state的组件。函数组件又叫做无状态组件(在rect16.8后引入了
React Hooks ,函数组件也能定义自己的状态)
了解了状态组件后我们来学习一下类组件中定义状态和渲染转态.
下面来看一段代码:
import reactDom from 'react-dom'
import React from 'react'
class Hello extends React.Component {
// 这里的state就是状态
state = {
list: [{ id: 1, name: '明天会更好' }],
isLoading: true
};
render () {
return <ul>
{this.state.list.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
}
}
const app = (
<div>
<Hello />
</div>
)
reactDom.render(app, document.getElementById('root'))
以上代码就是类组件中定义状态和渲染状态的一个基本使用.
事件绑定
当我们渲染了一个基本的页面后,想让页面有一个基本的交互效果就需要事件绑定.
事件绑定格式:
<元素 事件名1={ 事件处理函数1 } 事件名2={ 事件处理函数2 } ></元素>
// 事件名采用驼峰命名法:列如--onMouseEnter、onFocus、 onClick ......
示列代码:
import reactDom from 'react-dom'
import React from 'react'
class Hello extends React.Component {
fn () {
console.log('拉拉阿拉啦啦啦啦啦')
}
render () {
return <ul>
<p>点击按钮打印信息</p>
<button onClick={this.fn}>点我</button>
</ul>
}
}
const app = (
<div>
<Hello />
</div>
)
reactDom.render(app, document.getElementById('root'))
在写绑定事件的时候应该注意什么?
-
事件名是小驼峰命名格式
-
在类中补充方法
-
this.fn不要加括号:
onClick={ this.fn() }
先调用fn(),然后将fn的执行结果当做click事件的处理函数 -
别忘记了写this
事件对象
在react中,通过事件处理函数的形参来获取。事件对象通过回调函数的参数来获取。
示列:
handleClick(e)=> {
e.preventDefault()
console.log('单击事件触发了', e)
}
render() {
return (<div>
<button onClick={(e)=>{console.log('按钮点击了', e)}}>按钮</button>
<a href="http://itcast.cn/" onClick={this.handleClick}>看看</a>
</div>)
}
}
事件处理-this指向问题
通过一端代码我们来看看this的指向异常问题.
class App extends React.Component {
state = {
msg: 'hello react'
}
handleClick() {
console.log(this) // 这里的this是?
}
render() {
console.log(this) // 这里的this是?
return (
<div>
<button onClick={this.handleClick}>点我</button>
</div>
)
}
}
- render方法中的this指向的而是当前react组件。
- 事件处理程序中的this指向的是
undefined
那么为何会出现这种情况?
- 事件处理程序的函数式函数调用模式,在严格模式下,this指向
undefined
- render函数是被组件实例调用的,因此render函数中的this指向当前组件
即:
- class的内部,开启了局部严格模式
use strict
,所以this不会指向windowundefined
onClick={this.fn}
中,this.fn的调用并不是通过类的实例调用的,所以值是undefined
具体事件处理-this指向问题可以参考一下好程序员分享React-010-事件处理函数的this指向问题_好程序员IT的博客-CSDN博客
常见的this指向解决方案:
- Function.prototype.bind()
- 箭头函数
- class 的实例方法【推荐】
具体使用可参考上面链接地址