React笔记(七)
前言
eg:代表代码对照 若文章有误,欢迎读者留言反馈知识点回顾
- 插值 {} 变量,表达式,函数调用
- 动态属性 属性={ 变量 }
- 样式写法
className={ 变量 }
className={'active btn'}
className={ arr.join(' ') }
style={{ fontSize:'12px',color:变量 }}
- 循环
-
{arr.map((item,index)=>{return
- { item } }) }
-
{Object.keys(obj).map((item,index)=>{return
- 属性:{ item },属性值:{ ob[item] }
- }) }
- 组件基本认识
- 函数组件就是函数,函数名称大写,有return值,return的是jsx,函数没有实例,没有生命周期,没有状态,
没有this, 函数组件我们也可以叫纯函数,参数不变的情况下,函数组件也不会变化。 - 类组件就继承react中的父类,重写了render函数,函数中有return值,return是jsx。
- 组件中jsx必须有唯一的跟标签,组件名称遵循大驼峰
- 函数组件就是函数,函数名称大写,有return值,return的是jsx,函数没有实例,没有生命周期,没有状态,
- props
- 类组件中可以this.props.属性 可以获取父组件的值。
- 函数组件通过props.属性获取父组件的值。
- props只读,单项数据流,父组件更新数据,props中的数据也随之更新。props就是父组件流转给子组件的数据。
- 事件
- 语法:on + 事件类型(首字符大写) = 执行函数
- event 事件对象是混合事件对象
- react的事件对象和原生事件对象区别?
react为了更好的兼容性和跨平台。为了事件的统一管理,所有的事件绑定在document上,避免频繁解绑,提来性能。 - this问题
=>react中执行函数中默认是没有this的,需要手动传入,推荐使用箭头函数来作为我们的执行函数。
- props进阶
- props.children 类似vue中的匿名插槽,获取父组件中子组件占位符闭合标签中的内容。
- props校验
=> npm i -S prop-types
=> 语法:组件名.propTypes = { //适用于类组件和函数组件
arr:PropTypes.array //类型校验 number string bool fun object
}
=> 类组件专属写法 static propTypes = { num:PropTypes.number } - props默认值
=> 语法1:组件名.defaultProps = { num:0 } //定义默认值
=> 语法2:static defaultProps = { num:0} //只适用于类组件。
- 受控组件和ref使用(非受控组件)
=> state = { inputVal:’’ }
=>
=> handleClick = (e) => {
}this.setState({ inputVal:e.target.value })
// ref使用 简写
{ this.inputVal = inputVal } }/>
this.inputVal.value 就可以获取当前input的元素值 - 生命周期
挂载阶段:constructor getDerivedStateFromProps render componentDidMount(挂载后常用)
更新阶段:getDerivedStateFromProps shouldComponentUpdate render getSnapshotBeforeUpdate
销毁阶段: componentWillUnmount销毁前componentDidUpdate更新后
废弃生命周期: componentWillMount 挂载前 componentWillReceiveProps props改变就执行componentWillUpdate更新前
- 组件通信
- 父子通信
=>父组件传递属性变量或者函数给子组件,子组件使用或者调用函数来实现父子通信。 - 跨层级通信
=> 定义全局的context
=> 祖先组件通过mycontext.Provder 通过value属性存入数据cosnt mycontext = React.createContext() //定义context 参数设置默认值 export default mycontext //mycontext.Provder mycontext.Consumer export default { Provder,Consumer )
=>后代组件通过mycontext.Consumer 来获取数据 - eventbus通信,事件总线通信
=> 定义全局事件中心
=> 被调用组件添加自定义事件npm i -S events import { Emitter } from 'events' export default new EventEmitter()
=> 调用组件通过bus.emit 触发自定义事件 - redux
- 父子通信
- 传送门 Portal
- 作用:把某个子元素逃离父组件,逃离到body下面去。
- 语法:
{
ReactDOM.createPortal(要逃离的子元素,document.body)
}
- scu
- 作用:通过scu这个生命周期可以控制当前组件中的render要不要刷新,提高性能。
- 语法:
1
2
3
4
5
6
7shouldComponentUpdate(nextProps,nextState){
{/* suc要想正确使用,肯定要遵循不可变值 */}
if(nextProps.arr == this.state.arr){ // 父组件如果没有更新,我们就可以不更新render
return false
}
return true
} - suc简写
=> 类组件直接继承 PureComponent 得到一个浅比较的suc。
=> 函数组件的话,就使用memo这个高阶组件来实现浅比较的scu。
- hoc 高阶组件
高阶组件,组件作为参数,并且返回一个新组件的函数组件,我们叫高阶组件。
作用:抽离公共功能,抽离公共逻辑。1
2
3
4
5
6
7
8function HOC(Component){
return class newCom extends Component{
render(){
//{...this.props} 承上启下的作用
return <Component {...this.props}/>
}
}
}
记忆组件【计算属性】
记忆组件 实现类似计算属性的功能
记忆组件功能、特性:
- 缓存性:在参数不变的情况下,直接使用之前缓存的值
- 依赖性:依赖的参数发生改变,函数就会重新计算
使用
- 安装插件
npm i -S memoize-one- 引入memoize-one
import Memoize from ‘memoize-one’- 直接包裹函数
- 从memoize-one中引入memoize
代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35import React, { Component } from 'react'
// 记忆组件 实现类似计算属性的功能
/*
记忆组件功能、特性:
1. 缓存性:在参数不变的情况下,直接使用之前缓存的值
2. 依赖性:依赖的参数发生改变,函数就会重新计算
使用:
1. 安装插件
npm i -S memoize-one
2. 引入memoize-one
import Memoize from 'memoize-one'
3. 直接包裹函数
*/
// 引入memoize-one
import Memoize from 'memoize-one'
class MemoizeDemo extends Component {
getValue = Memoize((x, y) => {
console.log('函数执行了加法函数:', x, y)
return x + y
})
render() {
return (
<div>
<h3>记忆组件</h3>
<p>{this.getValue(1, 2)}</p>
<p>{this.getValue(1, 2)}</p>
<p>{this.getValue(2, 2)}</p>
</div>
)
}
}
export default MemoizeDemo