1.react特点
①声明式编码
②组件化编码
③React Native 编写原生应用
④高效(优秀的diffing算法)
⑤用于动态构建用户界面的js库(只关注视图)
2.React高效的原因
①使用虚拟DOM,不总是直接操作页面真实的DOM
②Diffing算法,最小化页面重绘
3.jsx
①全称:javaScript XML,react定义的一种类似于XML的js扩展语法:js+XML,
最终解析为js
②作用:用来简化创建虚拟DOM
jsx语法规则:
①定义虚拟DOM时,不要写引号。
②标签中混入js表达式时要用{}
③样式的类名指定使用className
④内联样式,要用style={{key:value}}的形式去写。
⑤只有一个根标签,并且标签必须闭合
⑥
(1)若小写字母开头,则将改标签转为html中同名元素,若html中无该标签对应的同名元素,则保持。
(2)若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错。
4.函数组件和类组件的基本区别
类组件有生命周期,函数组件没有
类组件需要继承 Class,函数组件不需要
类组件可以获取实例化的 this,并且基于 this 做各种操作,函数组件不行
类组件内部可以定义并维护 state, 函数组件为无状态组件(可以通过hooks实现)
函数组件相比较类组件,优点是更轻量与灵活,便于逻辑的拆分复用。
类组件使用:
import React, { Component } from 'react'
// 定义类组件
export default class ClassHanshu extends Component {
// 1.类中的构造器不是必须要写的,要对实例进行一些初始化的操作,如添加指定属性时才写
// 2.类中所定义的方法,都放在了类的原型对象上,供实例使用
// 3.如果A类继承了B类,且A类中写了构造器,那么A类构造器中的super是必须调用的
constructor() {
super()
this.state = {
flag: true,
count: 0
}
}
addCount() {
//constructor中的state不能直接修改
this.setState({
count: this.state.count += 1
})
}
changeText() {
this.setState({
flag: !this.state.flag
})
}
render() {
// 解构
const { flag, count } = this.state
console.log(flag);
return (
<div>CountClass
{/* 此处的this.state就不用再写了 */}
<p onClick={() => this.changeText()}>ad{flag ? "a" : "d"}</p>
<button onClick={() => this.addCount()}>{count}</button>
</div>
)
}
}
类组件中的state属性:
1.state是组件对象最重要的属性,值是对象
2.组件被称为“状态机”,通过更新组件的state来更新对应的页面显示
注意:
1.组件中render方法中的this为组件的实例对象
2.当组件自定义方法中的this为undefined时,可以通过函数对象的bind()强制绑定this或箭头函数
3.状态数据,不能直接修改或更新
5.ref的三种使用方法
import React, { Component } from 'react'
export default class ClassHanshu extends Component {
constructor() {
super()
}
showData() {
// js写法
// const btn = document.getElementById("btn")
// console.log(btn.value);
// console.log(this.refs.value);拿不到数据
// 解构 字符串ref用法
// const { btn } = this.refs
// console.log(btn.value);
}
showData1() {
// 回调ref
const { btn } = this
alert(btn.value)
}
render() {
return (
<div>
{/* 1.字符串ref的使用 */}
{/* <input id="btn" type="text" placeholder='点击按钮提示数据' />
<button onClick={() => this.showData()}>点击打印数据</button> */}
{/* <input ref="btn" type="text" placeholder='点击按钮提示数据' />
<button onClick={() => this.showData()}>点击打印数据</button> */}
{/* 2.回调ref */}
<input ref={c => this.btn = c} type="text" placeholder='点击按钮提示数据' />
<button onClick={() => this.showData1()}>点击打印数据</button>
</div>
)
}
}
import React, { Component } from 'react'
export default class ClassHanshu extends Component {
constructor() {
super()
// 3.createRef API方式
// React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点
// 该容器是专人专用的,所以不同的元素使用都要在constructor调用
this.myRef = React.createRef()
this.myRef1 = React.createRef()
}
showData() {
alert(this.myRef.current.value)
}
showData1() {
alert(this.myRef1.current.value)
}
render() {
return (
<div>
<input ref={this.myRef} type="text" placeholder='点击按钮提示数据' />
<button onClick={() => this.showData()}>点击打印数据</button>
<input ref={this.myRef1} type="text" placeholder='点击按钮提示数据' />
<button onClick={() => this.showData1()}>点击打印数据</button>
</div>
)
}
}
6.表单之非受控组件和受控组件
import React, { Component } from 'react'
export default class ClassHanshu extends Component {
constructor() {
super()
}
// 非受控组件
handleSubmit = (event) => {
// 阻止默认事件
event.preventDefault();
// 现用现取为非受控组件
const { username, password } = this
alert(`username的值是:${username.value},password的值是:${password.value}`)
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
用户名: <input type="text" name="username" ref={c => this.username = c} />
密码: <input type="password" name="password" ref={c => this.password = c} />
<button>登录</button>
</form>
</div>
)
}
}
import React, { Component } from 'react'
export default class ClassHanshu extends Component {
constructor() {
super()
this.state = {
username: "",
password: ""
}
}
// 受控组件,输入框输入的值可以实时获取到,建议使用受控组件可以省略掉ref(官网建议请勿过度使用ref)
// 表单提交的回调
handleSubmit = (event) => {
// 阻止默认事件
event.preventDefault();
const { username, password } = this.state
console.log(`username的值是:${username},password的值是:${password}`)
}
saveUsername = (event) => {
this.setState({
username: event.target.value
})
}
savePassword = (event) => {
this.setState({
password: event.target.value
})
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
用户名: <input type="text" name="username" onChange={this.saveUsername} />
密码: <input type="password" name="password" onChange={this.savePassword} />
<button>登录</button>
</form>
</div>
)
}
}
7.高阶函数和函数柯里化,解决受控组件代码冗余问题
import React, { Component } from 'react'
export default class ClassHanshu extends Component {
constructor() {
super()
this.state = {
username: "",
password: ""
}
}
handleSubmit = (event) => {
// 阻止默认事件
event.preventDefault();
const { username, password } = this.state
console.log(`username的值是:${username},password的值是:${password}`)
}
// 通过高阶函数解决受控组件代码冗余的问题
// 高阶组件 1.若A函数,接受的参数是一个函数,那么A就可以称为高阶函数
// 2.若A函数,调用的返回值依然是一个函数,那么A就可以称为高阶函数
// 常见高阶函数:promise setTimeout arr.map()等
// 函数柯里化:通过函数调用回继续返函数的方式,实现多次接收参数最后统一处理的函数编码形式
// 以下的saveForm就是高阶函数,里面返回的是箭头函数(柯里化)
saveForm = (dataType) => {
return (event) => {
this.setState({
[dataType]: event.target.value
})
}
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
用户名: <input type="text" name="username" onChange={this.saveForm("username")} />
密码: <input type="password" name="password" onChange={this.saveForm("password")} />
<button>登录</button>
</form>
</div>
)
}
}