一.React命令
npx create-react-app 文件名
二.React组件
函数式组件
-
先定义。
a,函数名称必须以大写字母开头。
b,必须有返回值,返回值表示该组件的结构,如果不想渲染任何内容,可以
return null
。 -
再使用。
a,
<函数名/>
,单标签闭合。b,
<函数名></函数名>
,双标签。
import ReactDOM from 'react-dom'
function Hello() {
return <div>这是第一个函数组件</div>
}
// const Hello = () => <h1>这是一个函数组件!</h1>;
// 把函数的名字作为标签名进行渲染,可以使用单闭合,或双标签的形式
ReactDOM.render(<Hello />, document.getElementById('root'))
类组件
a,使用 ES6 语法的 class 创建的组件,又称复杂组件或有状态组件。
b,类名称也必须要大写字母开头。
c,类组件应该继承 React.Component
父类,从而可以使用父类中提供的方法或者属性。
d,类组件必须提供 render()
方法,此方法中的 this 指向此组件的实例对象,此方法中必须要有 return 返回值。
class Hello extends React.Component {
render() {
return <div>这是第一个类组件</div>
}
}
ReactDOM.render(<Hello />, document.getElementById('root'))
三.组件状态
-
有状态组件:能定义 state 的组件,类组件就是有状态组件。
第一种是constructor
class App extends React.Component {
constructor() {
super()
this.state = {
list: [
{ id: 1, name: '明天会更好' },
{ id: 2, name: '今天' },
],
}
}
}
第二种state对应值是个对象
class App extends React.Component {
state = {
list: [
{ id: 1, name: '明天会更好' },
{ id: 2, name: '今天' },
],
}
// ...
}
-
无状态组件:不能定义 state 的组件,函数组件一般叫做无状态组件
四.props校验
-
安装并导入
prop-types
包。 -
使用
组件名.propTypes = {}
来给组件的 props 添加校验规则。 -
校验规则通过
PropTypes
对象来指定。import React, { Component } from 'react' import PropTypes from 'prop-types' class Test extends Component { render() { return ( <ul> {this.props.colors.map((item) => ( <li key={item}>{item}</li> ))} </ul> ) } } Test.propTypes = { colors: PropTypes.array, } export default Test
4.常见校验规则
-
常见类型:number、string、bool、array、func、object。
-
React 元素类型(JSX):element。
-
必填项:isRequired。
-
特定结构的对象:shape({})。
-
{
// 常见类型
fn1: PropTypes.func,
// 必选
fn2: PropTypes.func.isRequired,
// 特定结构的对象
obj: PropTypes.shape({
color: PropTypes.string,
fontSize: PropTypes.number
})
}
5.props默认值
1.通过 defaultProps
可以给组件的 props 设置默认值,在未传入 props 的时候生效。
2.利用 JS 自身的能力来完成
第一种通过 `defaultProps` 可以给组件的 props 设置默认值,在未传入 props 的时候生效。
import React, { Component } from 'react'
class Test extends Component {
render() {
return <div>{this.props.age}</div>
}
}
Test.defaultProps = {
age: 18,
}
export default Test
第二种利用 JS 自身的能力来完成
import React, { Component } from 'react'
class Test extends Component {
render() {
const { age = 18 } = this.props
return <div>{age}</div>
}
}
export default Test
五.类的静态属性
-
实例成员:通过实例才能访问的成员(属性或者方法),叫做实例成员。
-
静态成员:通过类或者构造函数本身才能访问的成员(一般是直接挂载到类上的或者通过 static 关键字定义的)。
六.React生命周期
react总共三个阶段挂载阶段----更新阶段----卸载阶段
1.挂载阶段:常用的生命周期函数有 3 个,执行顺序是 constructor => render => componentDidMount
constructor :创建组件时,最先执行 初始化 state 2. 创建 Ref 等
render: 每次组件渲染都会触发 渲染 UI
componentDidMount :组件挂载(完成 DOM 渲染)后 发送网络请求 和DOM 操作
2.更新阶段:常用的生命周期函数有 2 个,执行顺序是 render => componentDidUpdate。
触发更新:setState()
、forceUpdate()强制转换
、New props传入新值
(父组件进行了 render)
render :每次组件渲染都会触发 渲染 UI
componentDidUpdate:组件更新(完成 DOM 渲染)后 DOM 操作,可以获取到更新后的 DOM 内容,不要调用 setState
3.卸载阶段
触发时机:组件从页面中消失
ReactDOM.unmountComponentAtNode(document.getElementById('root'))
componentWillUnmount :组件卸载 执行清理工作(比如:清理定时器等、解绑事件等)
七.setState更新数据的特点
-
一般情况下,通过
setState()
方法来更新数据,表现是异步的。 -
也就是说当执行到 setState 这一行的时候,React 出于性能考虑,并不会马上进行调用来修改 state。
-
而是把这个以及后续的对象放到一个更新队列里面进行合并的操作,稍后才会从队列当中把和并后的数据取出来进行 setState 的操作。
-
也就是其实多次调用 setState() ,只会触发一次重新渲染。
-
不能立即拿到更新后的数据;多次进行 setState 会进行合并的操作。
解决方案
1.setState(updater, [callback])
this.setState({}, () => {
console.log('这个回调函数会在状态更新后立即执行')
})
2.使用 setState((preState) => {})
语法
// 初始
state = { count: 1 }
// 更新
this.setState((preState) => {
return {
count: preState.count + 1,
}
})
this.setState((preState) => {
return {
count: preState.count + 2,
}
})
// 输出
console.log(this.state.count) // 依然是 1