1. 状态 state
-
设置了stata的组件称之为有状态组件,没有设置state的组件称之为无状态组件。
-
组件中的数据:
class A extends Component{ state = {key:value} }
class A extends Component{ constructor(){ super(); this.state = { key:value } } }
-
在类中定义state(只能写这个名字)对象
state = {key:value}
-
不要直接修改state:
this.state.ok = 'ok'
使用
setState({key:value})
-
setState注意:
①在同步逻辑中,异步更新状态与真实dom;
②在异步逻辑中,同步更新状态与真实dom;
③接受第二个参数,是个回调函数,在这里状态与dom更新完毕。
2. 属性props(只读)
-
state是内部属性,props是为了更好地实现复用性,从外部接收数据。
-
某组件:
{/*属性*/} <MyNav title={this.title} leftBtn={isShowLeft}/>
-
MyNav.js
render(){ let {title,leftBtn}=this.props; return ( <div> {leftBtn && <button>left</button>} <p>{title}</p> <button>right</button> <img{...obj}/> </div> ) }
//属性验证 import myprop from 'prop-types' static propTypes={ title:myprop.string, letBtn:myprop.bool } //默认属性 static defaultProps={ title:'首页' }
-
函数式组件对于属性的应用会更简单一些,直接通过形参可以获得。
3. 属性及状态总结
- 属性是父组件对子组件的数据传输与操作。
- 状态是组件自己内部的数据。
4. 表单
-
受控组件:
①由React控制
②value绑定state中的值
③实现表单元素的change事件
④优化:可以使用name属性,统一完成change事件
⑤注意:选择框与其他表单元素获取值的方式不一样 -
非受控组件:
①由DOM控制
②在constructor中React.createRef()
5. 通信
-
父传子:属性值;
-
子传父:回调函数;
-
在父组件中对子组件进行ref标记,可以获取到子组件的引用;
-
中间人模式:由父组件充当中间人,利用子传父+父传子模式完成。
-
发布订阅模式:
let bus = { list:[], //存放订阅者 //订阅者 subscrible(cb){ this.list.push(cb); }, //发布者 publish(text){ this.list.forEach(cb => cb && cb(text)) } }
-
context状态树传参(官方提供):
//父组件 <GlobalContext.Provider value = { {a:1,b:2} }> <Child1></Child1> <Child2></Child2> </GlobalContext.Provider>
//子组件 <GlobalContext.Consumer> { value =>{ return ( <div>子组件{value}</div> ) } } </GlobalContext.Consumer>
注意:value是固定的关键词.
-
Redux
6. 插槽
-
默认形式:
//父组件 <Child> <p>插入任意内容<p/> </Child> //子组件 return ( <div> <p>子组件内部标签</p> {/* 以下内容是插槽内容,外部代码在此进行替代 */} {this.props.children} {/* 固定写法 */} </div> )
-
按顺序插入:
//父组件: <Child> <p>西游记<p/> <p>红楼梦<p/> <p>水浒传<p/> </Child> //子组件Child: return ( <div> {this.props.children[0]} {this.props.children[1]} {this.props.children[2]} </div> )
-
作用:
①提高代码的复用性;
②一定程度上减少父子通信。
7. 生命周期(钩子函数)
写在前边:只有类组件(函数组件需要hooks支持)
7.1 初始化阶段
-
componentWillMount
①组件即将挂载,render之前最后一次修改state的机会;
②常用于:state的初始化;
③备注:如果有警告,可使用UNSAFE_componentWillMount。 -
render:只能访问props与state,不能修改state及进行dom输出。
-
componentDidMount
①成功执行完毕render并完成dom节点的渲染,可以对dom修改。
②常用于:axios请求,订阅函数调用,计时器,dom操作。
7.2 运行中阶段
-
componentWillReceiveProps(nextProps):
①父组件修改属性触发;
②最先获取父组件传来的属性,可以在这里进行axios请求或者其他逻辑处理;
③备注:如果有警告,可使用UNSAFE_componentWillReceiveProps。 -
shouldComponentUpdate(nextProps,nextState):
①返回false,会阻止render的调用
②参数是被修改之后的新的属性及状态 -
componentWillUpdate:
①组件将要更新,不能修改该属性及状态
②备注:如果有警告,可使用UNSAFE_componentWillUpdate -
render:同1 render
-
componentDidUpdate(preProps,preState)
①可以修改dom
②参数是被修改之前的属性及状态
7.3 销毁阶段
componentWillUnmount:在删除组件前进行清理工作。
8. 新生命周期(推荐)
- 老钩子问题:
componentWillmount会重复触发多少次,如果绑定事件无法解绑。 - static getDeriveStateFromProps(nextProps,nextState)
①将属性转为状态;
②挂载之前于更新会执行;
③返回一个状态对象。