react中的组件用法
- React 组件介绍
- React 组件的两种创建方式
- React 事件处理
- 事件回调函数绑定 this 指向
- 有状态组件和无状态组件
- 组件中的 state 和 setState()
- 表单处理
React 组件介绍
react组件的特点
- 组件是 React 的一等公民,使用 React 就是在用组件
- 组件表示页面中的部分功能
- 组合多个组件实现完整的页面功能
- 特点:可复用、独立、可组合
React 组件的创建
有两种方式去创建组件:
- 函数式(无状态组件)
- class extend(有状态组件)
使用函数创建组件
示例
Hello.js
在这个文件中用函数声明的方式来创建组件。
import React from 'react'
function Hello() {
return (
<div>这是我的第一个函数组件!</div>
)
}
export default Hello
函数组件:使用 JS 的函数(或箭头函数)创建的组件。
- 函数名称必须以大写字母开头,使用大驼峰命名法
- 函数组件必须有返回值,表示该组件的结构
index.js
在这个入口文件中引入组件
import React from 'react';
import Hello from './Hello'
ReactDOM.render(
<Hello/>,
document.getElementById('root')
);
渲染函数组件:用函数名作为组件标签名
组件标签可以单闭合
使用class创建组件
index.js # 入口使用组件
Hello.js # 组件
使用 ES6 的 class关键字 创建的组件 ,类组件应该继承 React.Component 父类,从而可以使用父类中提供的方法和属性
示例
Hello.js
import React from 'react'
class Hello extends React.Component {
render () {
return <div>Hello Class Component!</div>
}
}
export default Hello
- 类名称也必须以大写字母开头,使用
大驼峰命名法
(必须) - 类组件必须提供 render() 方法
- render() 方法必须有返回值,表示该组件的结构
index.js
import React from 'react';
import Hello from './Hello'
ReactDOM.render(
<div><Hello/></div>,
document.getElementById('root')
);
注意: 通过标签名来引用组件。
React 事件处理
事件绑定
- React 事件绑定语法与 DOM 事件语法相似
- 语法:on+事件名称={事件处理程序fn},比如:onClick={() => {}}
- 注意:React 事件采用小驼峰命名法,比如:onMouseEnter、onFocus
示例
import React from 'react'
class Hello extends React.Component {
f1 () {
console.log(''f1')
}
render () {
return (<div>
<button onClick={this.f1}>按钮1</button>
</div>)
}
}
export default Hello
与vue中的template不同:vue中是"",不需要this,可以加括号,写f1()
this绑定
import React from 'react'
class Hello extends React.Component {
num = 0
f1 () {
console.log(this.num)
}
f2 = () => {
console.log(this.num)
}
render () {
return (<div>
<button onClick={this.f1}>按钮1</button>
<button onClick={this.f1.bind(this)}>按钮1.bind this</button>
<button onClick={this.f2}>按钮2</button>
</div>)
}
}
export default Hello
说明,上面的class的定义中,我们定义了一个成员属性 num, 两个成员方法 f1,f2,其中f2是箭头函数的格式。
在第一个按钮上,通过了bind(this)来绑定this。因为onClick只是定义响应函数,这个响应函数是在用户点击按钮时才会执行的,如果不先进行this的绑定,则该函数内的this会在这个函数被调用时动态地由调用这个函数的对象来决定,这里就会产生this指向的问题。
而采用了箭头函数去定义方法时,由于箭头函数内部的this具有静态作用域的效果,所以它不会有问题,会指向定义这个方法时那个组件。
在涉及this时,必须手动绑定this,或者是采用箭头函数来定义方法。
事件对象
- 可以通过事件处理程序的默认参数获取到事件对象
- React 中的事件对象叫做:合成事件(对象)
- 合成事件:兼容所有浏览器,无需担心跨浏览器兼容性问题
import React from 'react'
class Hello extends React.Component {
f3 (e) {
console.log(e)
}
render () {
return (<div>
<button onClick={this.f3}>按钮3</button>
</div>)
}
}
export default Hello
点击之后的效果
除事件对象之外的参数
如果希望事件发生之后,在其响应函数中除了事件对象之外,还要补充某些其它的参数,则可以如下去写:
import React from 'react'
class Hello extends React.Component {
f4 (e, p) {
console.log(e, p)
}
render () {
return (<div>
<button onClick={(e)=>{ this.f4(e,200) }}>按钮4</button>
</div>)
}
}
export default Hello
理解onClick={(e)=>{ this.f4(e,200) }}
这句代码,外层的{}表示是一个
有状态组件和无状态组件
Vue =》 script {data(){reutn {key:val}}} => 数据驱动视图
-
函数组件->无状态组件
-
类组件class->有状态组件
有状态组件和无状态组件的区别
函数组件又叫做无状态组件,类组件又叫做有状态组件。
- 状态(state)即数据,某个时刻的值
- 类组件有自己的状态,负责更新 UI,让页面“动” 起来
- 函数组件没有自己的状态,只负责数据展示(静)
- 比如计数器案例中,点击按钮让数值加 1 。0 和 1 就是不同时刻的状态,而由 0 变为 1 就表示状态发生了变 化。状态变化后,UI 也要相应的更新。React 中想要实现该功能,就要使用有状态组件来完成。
类组件中的 state 和 setState()
类似于Vue 组件中data
状态(state)即数据,是组件内部的私有数据,只能在组件内部使用,state 的值是对象,表示一个组件中可以有多个数据 .
state的定义和获取
有两种方式去定义state:
- 写在构造器内部
- 不写构造器,直接简写
获取:
- this.state.XXXX
import React from 'react';
export default class Hello extends React.Component {
// 方式一:写构造器
constructor () {
super()
this.state = {
count: 1
}
}
// 方式二:简写
state = {
count: 1
}
render () {
return (<div>Hello {this.state.count}</div>)
}
}
5.2 setState()修改状态
不要直接修改 state 中的值,这是错误的。this.state.count=2这样写虽然不报错,但是,视图中的内容不会变化。
语法格式
this.setState({ key:val, key2:val2 })
注意:
- setState() 作用:
- 修改 state
- 更新UI
- 思想:数据驱动视图
import React from 'react';
export default class Hello extends React.Component {
constructor () {
super()
}
state = {
count: 1
}
f1 = ()=> {
const count = this.state.count+1
this.setState({count})
}
render () {
return (
<div>
Hello {this.state.count}
<button onClick={this.f1}>+1</button>
</div>)
}
}
可以进一步通过解构赋值来减少render()中的this的出现。
import React from 'react';
export default class Hello extends React.Component {
constructor () {
super()
}
state = {
count: 1
}
f1 = ()=> {
const count = this.state.count+1
this.setState({count})
}
render () {
const {state:{count}, f1} = this
return (
<div>
Hello {count}
<button onClick={f1}>+1</button>
</div>)
}
}
实现双向绑定
定义
- HTML 中的表单元素是可输入的,也就是有自己的可变状态
- 而React 中可变状态通常保存在 state 中,并且只能通过 setState() 方法来修改
- React将 state 与表单元素值value绑定到一起,由 state 的值来控制表单元素的值
- 受控组件:其值受到 React 控制的表单元素
步骤
- 给表单元素value绑定state状态
- 在 change 事件处理程序中来修改对应的state
示例:
import React from 'react';
export default class Hello extends React.Component {
state = {
count: 1
}
hInput = (e)=> {
const count = e.target.value
this.setState({count})
}
render () {
const {state:{count}, hInput} = this
return (
<div>
{count}<br/>
<input value={count} onChange={hInput} type="text"/>
</div>)
}
}
适用场景:获取表单元素数据(双向绑定)
非受控组件
定义
- 说明:借助于 ref,使用原生 DOM 方式来获取表单元素值
- ref 的作用:获取 DOM 或组件实例
步骤
- 调用 React.createRef() 方法创建一个 ref 对象 (打造一个锚点)
- 把ref对象作为一个属性添加到组件上(把锚点放在目标上)
- 通过ref对象来引用 (通过锚点来获取目标引用)
示例
import React from 'react';
export default class Hello extends React.Component {
inputRef = React.createRef()
f1 = ()=> {
console.log(this.inputRef.current.value)
}
render () {
const {inputRef, f1} = this
return (
<div>
<input ref={inputRef} type="text"/>
<button onClick={f1}>获取input元素的值</button>
</div>)
}
}
注意
- 不能在函数组件上使用ref,因为它没有实例。
- 不要过度使用Refs。
适用场景:
- 操作DOM元素和类组件
- 控制元素样式或媒体播放等
小结
- 组件的两种创建方式:函数组件和类组件
- 无状态(函数)组件,负责静态结构展示
- 有状态(类)组件,负责更新 UI ,让页面动起来
- 类组件:绑定事件注意 this 指向问题 =》箭头函数
- 推荐使用受控组件(双向绑定)来处理表单 -> 受控的input->1. value为state数据2.onChange={修改state=》setS}
- 完全利用 JS 语言的能力创建组件,这是 React 的思想